Let the user save an image of a smooth curve in C#

[smooth curve]

The post Let the user draw a smooth curve in C# shows how you can let the user draw a smooth curve. This example extends that one to let you save the curve in an image file.

There are a few approaches that you might take. The following sections describe two approaches.

Saving the PictureBox Image

The post Get the image of a control or form, or a form’s client area in C# shows how you can capture a control’s image in a bitmap. The following code shows the GetControlImage method.

private Bitmap GetControlImage(Control ctl)
{
    Bitmap bm = new Bitmap(ctl.Width, ctl.Height);
    ctl.DrawToBitmap(bm,
        new Rectangle(0, 0, ctl.Width, ctl.Height));
    return bm;
}

This method creates a Bitmap with the same size as the control. It then calls the control’s DrawToBitmap method to draw the control’s image onto the Bitmap. It finishes by returning the Bitmap.

When you select the File menu’s Save Image command, the following code uses the GetControlImage method to save an image of the example’s PictureBox.

// Save an image of the PictureBox.
private void mnuFileSaveImage_Click(object sender, EventArgs e)
{
    if (sfdPicture.ShowDialog() == DialogResult.OK)
    {
        // Get an image of the PictureBox.
        using (Bitmap bm = GetControlImage(picCanvas))
        {
            // Save the image.
            SaveImage(bm, sfdPicture.FileName);
        }
    }
}

This code displays a SaveFileDialog. If you select a file and click Save, the program calls the GetControlImage method to get an image of the program’s PictureBox. It then uses the SaveImage method described in the post Save images with an appropriate format depending on the file name’s extension in C# to save result into an image file.

[smooth curve]

The picture on the right shows the result. Notice that the picture includes the PictureBox control’s borders. The easiest way to fix that is to make the control not display a border. Another approach is to find the client area inside the control’s image and copy it out of the bitmap. To use that approach, look at the way the earlier post gets an image of the form’s client area.

Saving a Drawn Image

A better method than the previous one is to draw the curve on a new bitmap. This is a bit more work than the previous method, but the result is easier to control.

To use this technique, first move all of the drawing code into a separate method that takes a Graphics object as a parameter. Then make the Paint event handler call that method.

The following code shows how this example does this.

// Draw the curve and its points.
private void picCanvas_Paint(object sender, PaintEventArgs e)
{
    DrawTheCurve(e.Graphics, true);
}

// Draw the curve.
private void DrawTheCurve(Graphics gr, bool draw_points)
{
    gr.SmoothingMode = SmoothingMode.AntiAlias;

    // Draw the curve.
    if (Points.Count > 1)
    {
        // Make a pen to use.
        using (Pen pen = new Pen(Color.Blue))
        {
            // See if we're currently drawing.
            if (Drawing)
            {
                // Use a dashed pen.
                pen.DashPattern = new float[] { 5, 5 };
            }

            // Draw the curve.
            gr.DrawCurve(pen, Points.ToArray(), Tension);
        }
    }

    // Draw the points.
    if (draw_points && Drawing && (Points.Count > 0))
    {
        const int r = 4;
        foreach (Point point in Points)
        {
            Rectangle rect = new Rectangle(
                point.X - r, point.Y - r, 2 * r, 2 * r);
            gr.FillRectangle(Brushes.White, rect);
            gr.DrawRectangle(Pens.Black, rect);
        }
    }
}

The Paint event handler simply calls the new DrawTheCurve method passing it the e.Graphics parameter and the value true to indicate that DrawTheCurve should draw boxes at the curve’s control points.

The DrawTheCurve method draws the curve more or less as the earlier example did. The only differences are that it takes its Graphics object as a parameter and that it only draws the control points if its draw_points parameter is true.

Now that you have the code that draws the curve in a separate method, you can use that method for other things. For example you could use it to draw the curve on the printer. I’ll leave that for you to do if you like. You may want to modify the drawing code to use different colors, thicker lines, of a different scale for the printer.

When you select the File menu’s Save Drawing command, the following code uses the DrawTheCurve method to save a drawing of the curve in an image file.

// Draw the curve onto a bitmap and save it.
private void mnuFileSaveDrawing_Click(object sender, EventArgs e)
{
    if (sfdPicture.ShowDialog() == DialogResult.OK)
    {
        // Make a Bitmap.
        int wid = picCanvas.ClientSize.Width;
        int hgt = picCanvas.ClientSize.Height;
        using (Bitmap bm = new Bitmap(wid, hgt))
        {
            // Draw the curve on the bitmap.
            using (Graphics gr = Graphics.FromImage(bm))
            {
                DrawTheCurve(gr, false);
            }

            // Save the image.
            SaveImage(bm, sfdPicture.FileName);
        }
    }
}

This code displays a SaveFileDialog. If you select a file and click Save, the code then creates a Bitmap with the same dimensions as the PictueBox control’s client area. It makes an associated Graphics object and passes it into the DrawTheCurve method. The code finishes by calling the SaveImage method to save the result.

Conclusion

This example shows how to let the user save a smooth curve into a file. More importantly it shows how you can place drawing code in a separate method so you can reuse it in different places. That lets you easily display your smooth curve on the screen, save it into an image file, or send the drawing to the printer.


Download Example   Follow me on Twitter   RSS feed   Donate




About RodStephens

Rod Stephens is a software consultant and author who has written more than 30 books and 250 magazine articles covering C#, Visual Basic, Visual Basic for Applications, Delphi, and Java.
This entry was posted in drawing, graphics and tagged , , , , , , , , , , . Bookmark the permalink.

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.