Let the user scribble on a PictureBox in C#

[scribble]

The Graphics class provides a DrawLines method that draws a series of connected lines, which is sometimes called a polyline. This program lets the user create a series of polylines.

The program stores the points that make up a polyline as a List<Point>. It stores a series of polylines in a List<List<Point>>. It keeps track of the new polyline that the user is drawing in the variable NewPolyline.

// The polylines we draw.
private List<List<Point>> Polylines = new List<List<Point>>();

// The new polyline we are drawing.
private List<Point> NewPolyline = null;

When the user presses the mouse down, the following code creates a new polyline.

// Start drawing.
private void picCanvas_MouseDown(object sender, MouseEventArgs e)
{
    // Create the new polyline.
    NewPolyline = new List<Point>();
    Polylines.Add(NewPolyline);

    // Add the first point.
    NewPolyline.Add(e.Location);
}

This code the NewPolyline list and then adds the mouse’s position to it.

When the user moves the mouse, the following code adds the mouse’s new location to the new polyline.

// Continue drawing.
private void picCanvas_MouseMove(object sender, MouseEventArgs e)
{
    if (NewPolyline == null) return;
    NewPolyline.Add(e.Location);
    picCanvas.Refresh();
}

This code checks whether the user is making a new polyline by checking whether NewPolyline == null. If there is a new polyline, the code adds the mouse’s current location to the new polyline and refreshes the PictureBox to draw it as it is so far.

When the user releases the mouse, the following code removes the new polyline if it contains only a single point.

// Stop drawing.
private void picCanvas_MouseUp(object sender, MouseEventArgs e)
{
    if (NewPolyline == null) return;

    // See of the new polyline contains more than 1 point.
    if (NewPolyline.Count < 2)
    {
        // Remove it.
        Polylines.RemoveAt(Polylines.Count - 1);
    }

    NewPolyline = null;
    picCanvas.Refresh();
}

The only other interesting piece of code in this example is the PictureBox‘s Paint event handler, which draws the polylines.

// Redraw.
private void picCanvas_Paint(object sender, PaintEventArgs e)
{
    e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
    e.Graphics.Clear(picCanvas.BackColor);

    // Draw the polylines.
    foreach (List<Point> polyline in Polylines)
    {
        e.Graphics.DrawLines(Pens.Black, polyline.ToArray());
    }
}

This code sets the Graphics object’s SmoothingMode to draw smooth lines. It then loops through the polylines and draws them.


Download Example   Follow me on Twitter   RSS feed   Donate




This entry was posted in drawing, graphics and tagged , , , , , , , , , , , . Bookmark the permalink.

3 Responses to Let the user scribble on a PictureBox in C#

  1. John says:

    Nice program.
    What if you want a picture in the picturebox, and you want to persist the picture with whatever the user has scribbed on it? I tried adding a picture to the picturebox but it does not show up.

  2. RodStephens says:

    To display a picture behind the scribble, I can think of three approaches offhand.

    1. Set the control’s Image property to the picture. Then DO NOT call e.Graphics.Clear in the Paint event handler. (That call would erase the picture.) This works in this example, but might not work if you draw something that depends on the size of the control. For example, if you draw an ellipse that fills the PictureBox, then you need the call to Clear to get rid of old ellipses when you resize. This is probably the easiest approach.

    2. The same as 1 except set the control’s BackgroundImage property instead of Image. In this case, you may want to make the control non-resizable so it doesn’t tile the image. Or you might want the image to tile. This has the same drawbacks as 1.

    3. Create a Bitmap in memory, do all of the drawing on that, and display the result. This gives you total control over the result, although it’s more work.

    I’m not sure if you also want to save the result into a file. If you use approach:

    3. This is easy because you already have the Bitmap holding the image. Use this post to save the Bitmap into a file:

    Save images with an appropriate format depending on the file name’s extension in C#

    1. or 2. Use this post to save an image of the PictureBox into a Bitmap:

    Get the image of a control or form, or a form’s client area in C#

    Then use the earlier post to save the result into a file.

    I’ll post a revised version of the program when I have a chance.

  3. Pingback: Let the user scribble on a background image in C# - C# HelperC# Helper

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.