C # GDI + implements rubber band technology

Source: Internet
Author: User
Tags linecap polyline
There should be a lot of people looking for this information, to see what I do, maybe it will help you, I hope so.

In order to achieve the rubber band technology, I used two ways:
The first is to use the Controlpaint.drawreversibleline (point Start,point end, Color BackColor) method, which draws a reversible line with the specified background color within the specified starting and ending points on the screen. Drawing the same line again reverses the result of the method. Using this method to draw a line is similar to reversing an area of the screen, but it provides better performance for a wider range of colors.
Note that the start and end end points of this are relative to the screen, so I use the Pointtoscreen (point P) method to convert.
Unfortunately, in the mouse drag, the drawing of the transformation (that is, a segment, in my field of study, I call the line to take the segment is transformed) without line. In order to draw a transform, it is only possible to redraw it with a left-click (if you don't need a thread, comment out the invalidate () in the MouseDown () method). Because the Drawreversibleline () method is used in the background color backcolor= (a,r,g,b), it can automatically invert the color, and the use of the left-click to redraw the need to use the reverse color of the background color reversebackcolor= ( A ', R ', G ', B '), so how do you get the inverse color of the background color? I use 255 to reduce the original background color of the r,g,b, and the transparency of the same, that is, a ' =a;r ' =255-r;g ' =255-g;b ' =255-b, and then use this color-defined brush to repaint.

Using system;using system.collections.generic;using system.componentmodel;using system.data;using System.Drawing; The Using system.text;using system.windows.forms;using system.drawing.drawing2d;//contains this advanced two-dimensional graphics namespace namespace Reverselines            {public partial class Form1:form {public Form1 () {InitializeComponent ();            Activates the double buffering technique SetStyle (Controlstyles.userpaint, true);            SetStyle (Controlstyles.allpaintinginwmpaint, true);        SetStyle (Controlstyles.doublebuffer, true); } private point[][] Trangroup = new point[1000][];//transform Group private int trannumb = 0;//transform ordinal private int p Ushnumb = 0;//left button pressed: 0 is the start of the transformation, 1 is the end of the private point curp;//storage transformation when the mouse's current points of the STARTP, the start of the oldp;//transformation and the mouse movement Current Point Private Graphics g0,g3;//window drawing surface and temporary drawing surface with double buffering private point endpoint;//storage Right-click to discard draw connected transform mouse dot private Color clr,clr1;//Gets the background color of the form and reverses the background color of the private pen p;//the pen that is used to redraw the transform Bitmap Bitmap = null;Bitmap for double buffering private void Form1_paint (object sender, PaintEventArgs e) {g0 = E.graphics;             Bitmap = new Bitmap (clientsize.width, clientsize.height);//create temporary bitmap g3 = graphics.fromimage (bitmap);//create drawing surface from bitmap G3. Clear (this. BackColor);//clear the background color G3. SmoothingMode = smoothingmode.antialias;//Set anti-aliasing smoothing mode//Redraw transform on temporary bitmap, anti-aliasing, with line-over for (int i = 0; I < Tran Numb; i++) {G3.            DrawLine (P, trangroup[i][0], trangroup[i][1]); }//Copy the temporary bitmap to the form drawing surface G0.        DrawImage (bitmap, 0, 0); private void Form1_Load (object sender, EventArgs e) {clr = this. backcolor;//gets the form background color CLR1 = Color.FromArgb (CLR. A, 255-CLR. R, 255-CLR. G, 255-CLR. B);//invert background color p = new Pen (CLR1, 1);//define the PEN//custom line used to draw the transform when the left mouse button is pressed and moved adjustablearrowcap cap = n            EW Adjustablearrowcap (3, 3); Cap.            Widthscale = 3; Cap. BasecAP = Linecap.square; Cap.            Height = 3;            P.customendcap = cap;            Loops the transform in the transform group for (int i = 0; i < i++) {Trangroup[i] = new POINT[2]; }} private void Form1_mousedown (object sender, MouseEventArgs e) {Graphics g2 = Cr            Eategraphics ();                Determine the number of transformations if (Trannumb >= 999) {pushnumb = 0;                Capture = false;            Return }//Left button to press if (E.button = = MouseButtons.Left) {if (Pushnumb = = 0)//To determine if it is a polyline                        Start {if (endpoint.x! = e.x | | Endpoint.y! = e.y) {                        pushnumb++;                        startp.x = e.x;                        STARTP.Y = e.y;                        oldp.x = e.x;                        OLDP.Y = e.y;         capture = true;//Mouse}       } else if (Pushnumb = = 1)//If it is not the beginning of a new polyline {controlpaint.drawrevers                    Ibleline (Pointtoscreen (STARTP), Pointtoscreen (new Point (e.x, e.y)), CLR);                                                           Controlpaint.drawreversibleline (Pointtoscreen (STARTP), Pointtoscreen (new Point (e.x, e.y)), CLR);                    The transform is deposited into the transformation group curp.x = e.x;                    CURP.Y = e.y;                    Trangroup[trannumb][0] = STARTP;                    TRANGROUP[TRANNUMB][1] = curp;                    trannumb++;                    startp.x = e.x;                    STARTP.Y = e.y;                    Stores the coordinates of the last point of a polyline endpoint.x = e.x;                Endpoint.y = e.y;                }}//Right-click the IF (E.button = = mousebuttons.right) {                The number of transformations exceeds the maximum if of the transform group (Pushnumb = = 0) return; The number of transformations does not exceed the changeChange Group Max Pushnumb = 0;//a polyline end Capture = false;//release mouse//Draw last transform            Controlpaint.drawreversibleline (Pointtoscreen (STARTP), Pointtoscreen (new Point (e.x, e.y)), CLR);            }//Fail re-painting, for antialiasing Invalidate (); G2.        Dispose ();             } private void Form1_mousemove (object sender, MouseEventArgs e) {Graphics G1 = CreateGraphics ();                Left-click and move the mouse if (pushnumb = = 1) {if (oldp.x! = e.x | | oldp.y! = E.Y) {//Draws a reversible line with the specified background color within the specified starting and ending points on the screen//drawing the same line again reverses the result of the method.                    Using this method to draw a line is similar to reversing an area of the screen,//But it provides better performance for a wider range of colors.                    Controlpaint.drawreversibleline (Pointtoscreen (STARTP), Pointtoscreen (OLDP), CLR);                                       Controlpaint.drawreversibleline (Pointtoscreen (STARTP), Pointtoscreen (new Point (e.x, e.y)), CLR); Stores the end point of a transformation as the starting point for the next transformation                    oldp.x = e.x;                OLDP.Y = e.y; }} G1.        Dispose (); }//frees the resource private void form1_formclosed (object sender, Formclosedeventargs e) {G3.            Dispose (); Bitmap.            Dispose (); G0.        Dispose (); }    }}

The second is to use the background color directly to draw the transformation that needs to be erased when the mouse is dragged, and to draw a definite transform with the current brush. In this way, the mouse can be dragged when the drawing of the transformation band line.

Using system;using system.collections.generic;using system.componentmodel;using system.data;using System.Drawing; Using system.text;using system.windows.forms;using system.drawing.drawing2d;namespace Shiqu2{public partial class for            M1:form {public Form1 () {InitializeComponent ();            Activates the double buffering technique SetStyle (Controlstyles.userpaint, true);            SetStyle (Controlstyles.allpaintinginwmpaint, true);        SetStyle (Controlstyles.doublebuffer, true); } private point[][] Trangroup = new point[1000][];//transform Group private int trannumb = 0;//transform ordinal private int p Ushnumb = 0;//left button pressed: 0 is the start of the transformation, 1 is the end of the private point curp;//storage transformation when the mouse's current points of the STARTP, the start of the oldp;//transformation and the mouse movement Current point private graphics G0, g3;//window drawing surface and temporary drawing surface with double buffering public Pen curpen;//a transform to determine and draw when the brush private point E ndpoint;//Store Right-click to discard draw connected transform mouse point private Color clr;//get form background color private pen p;//pen private Bitmap bi when redrawing transformsTMap = null;//bitmap with double buffering private void Form1_paint (object sender, PaintEventArgs e) {G0 = E.graphic            S            Bitmap = new Bitmap (clientsize.width, clientsize.height);//create temporary bitmap g3 = graphics.fromimage (bitmap);//create drawing surface from bitmap G3. Clear (this. BackColor);//clear the background color G3. SmoothingMode = smoothingmode.antialias;//Set anti-aliasing smoothing mode//Redraw existing transformations on the temporary bitmap, antialiasing, with line-over for (int i = 0; i < T Rannumb; i++) {G3.            DrawLine (Curpen, trangroup[i][0], trangroup[i][1]); }//Copy the temporary bitmap to the form drawing surface G0.        DrawImage (bitmap, 0, 0); private void Form1_Load (object sender, EventArgs e) {curpen = new Pen (Color.Black, 1);//define a transform Determines and draws the brush used by CLR = this.  backcolor;//get the form background color p = new Pen (CLR, 1);//define the mouse movement is redraw so the brush//Custom line Adjustablearrowcap cap =            New Adjustablearrowcap (3, 3); Cap.            Widthscale = 3; Cap. Basecap = Linecap.square;            Cap.            Height = 3;            Curpen.customendcap = cap;            P.customendcap = cap;            Initializes the transform in the drawing transform group for (int i = 0; i < i++) {Trangroup[i] = new Point [2]; }} private void Form1_mousedown (object sender, MouseEventArgs e) {Graphics g2=c            Reategraphics ();                Determine the number of transformations if (Trannumb >= 999) {pushnumb = 0;                Capture = false;            Return }//Left button to press if (E.button = = MouseButtons.Left) {if (Pushnumb = = 0)//To determine if it is a polyline                        Start {if (endpoint.x! = e.x | | Endpoint.y! = e.y) {                        pushnumb++;                        startp.x = e.x;                        STARTP.Y = e.y;                        oldp.x = e.x;                        OLDP.Y = e.y;          Capture = true;//Capturing mouse          }} else if (Pushnumb = = 1)//If it is not the beginning of a new polyline { G2.                    DrawLine (Curpen, STARTP, New Point (e.x, e.y));                    The transform is deposited into the transformation group curp.x = e.x;                    CURP.Y = e.y;                    Trangroup[trannumb][0] = STARTP;                    TRANGROUP[TRANNUMB][1] = curp;                    trannumb++;                    startp.x = e.x;                    STARTP.Y = e.y;                    Stores the coordinates of the last point of a polyline endpoint.x = e.x;                Endpoint.y = e.y;                 }}//Right-click the IF (E.button = = mousebuttons.right) {//transform number exceeds the maximum of the transform group                if (Pushnumb = = 0) return; The number of transformations does not exceed the transform group maximum pushnumb = 0;//a polyline end Capture = false;//release Mouse}//fail redraw            , for anti-aliasing Invalidate (); G2.        Dispose (); } private void Form1_mousemove (object sender, MouseEventArgs e) {Graphics G1 = CreateGraphics (); Left-click and move the mouse if (Pushnumb ==1) {if (OLDP. X!=e.x| | OLDP. Y!=e.y) {G1. DrawLine (P, STARTP, OLDP);//Draw the original transform G1 with the background color.  DrawLine (Curpen, STARTP, New Point (e.x, e.y)), or///////////Use current brush to draw current transform//To prevent them from being erased for                    (int i = 0; i < trannumb; i++) {G1.                    DrawLine (Curpen, trangroup[i][0], trangroup[i][1]);                    }//Stores the end of a transform as the starting point for the next transformation oldp.x = e.x;                OLDP.Y = e.y;             }}} private void Form1_formclosed (object sender, Formclosedeventargs e) { Frees the resource G3.            Dispose (); Bitmap.            Dispose (); G0.                  Dispose (); }    }}

Both methods use a double-buffering technique: first create a bitmap bitmap of the same size and client area, create a temporary drawing surface G3 with a bitmap, and then draw the transformation on the G3, and then use the form drawing surface g to draw the bit drawing.
Anti-aliasing technology: just a word g3. SmoothingMode = Smoothingmode.antialias, but note that anti-aliasing is not possible with left-click and mouse drag.

  • Related Article

    Contact Us

    The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

    If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.