How to save a picturebox control as a jpeg file after it's edited
Asked Answered
C

5

10

I have a PictureBox on my Windows Forms application.

I load a picture in it and I have enabled the Paint event in my code. It draws a rectangle.

Like this:

private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
    Graphics gr = e.Graphics;
    Pen p = new Pen(Color.Red);
    p.Width = 5.0f;
    gr.DrawRectangle(p, 1, 2, 30, 40);
}

And I click the "save" button:

private void button2_Click(object sender, EventArgs e)
{
    pictureBox1.Image.Save(@"C:\Documents and Settings\tr1g3800\Desktop\WALKING\30P\100000test.jpg",ImageFormat.Jpeg);
}

But the saved file never contains the rectangle that I drew.

Does anyone have any idea?

Cardona answered 30/6, 2009 at 12:53 Comment(0)
L
5

You probably shouldn't draw directly on the PictureBox.

You need to use a Bitmap instead. Try putting the bitmap in the PictureBox.Image and then call Save().

Check this for more details

Lo answered 30/6, 2009 at 12:57 Comment(0)
C
6

Thanks.Your anwers all helped. This worked

        private void button1_Click(object sender, EventArgs e)
    {
        pictureBox1.ImageLocation=@"C:\Documents and Settings\tr1g3800\Desktop\WALKING\30P\100000.jpg" ;
    }

    private void button2_Click(object sender, EventArgs e)
    {
        pictureBox1.Image.Save(@"C:\Documents and Settings\tr1g3800\Desktop\WALKING\30P\100000test.jpg",ImageFormat.Jpeg);
    }

    private void pictureBox1_Paint(object sender, PaintEventArgs e)
    {

    }

    private void button3_Click(object sender, EventArgs e)
    {
        Bitmap bmp = new Bitmap(pictureBox1.Image);
        Graphics gr = Graphics.FromImage(bmp);
        Pen p = new Pen(Color.Red);
        p.Width = 5.0f;
        gr.DrawRectangle(p, 1, 2, 30, 40);
        pictureBox1.Image = bmp;
    }
Cardona answered 30/6, 2009 at 13:21 Comment(1)
You shold usie the "using( ... ) { ... }" pattern. Now, you can have some memory leaks. And if some answer solve your answer, you should accept it ;).Vertex
L
5

You probably shouldn't draw directly on the PictureBox.

You need to use a Bitmap instead. Try putting the bitmap in the PictureBox.Image and then call Save().

Check this for more details

Lo answered 30/6, 2009 at 12:57 Comment(0)
O
4

Here is my solution with additional support to various file types:

    public void ExportToBmp(string path)
    {
        using(var bitmap = new Bitmap(pictureBox.Width, pictureBox.Height))
        {
        pictureBox.DrawToBitmap(bitmap, pictureBox.ClientRectangle);
        ImageFormat imageFormat = null;

        var extension = Path.GetExtension(path);
        switch (extension)
        {
            case ".bmp":
                imageFormat = ImageFormat.Bmp;
                break;
            case ".png":
                imageFormat = ImageFormat.Png;
                break;
            case ".jpeg":
            case ".jpg":
                imageFormat = ImageFormat.Jpeg;
                break;
            case ".gif":
                imageFormat = ImageFormat.Gif;
                break;
            default:
                throw new NotSupportedException("File extension is not supported");
        }

        bitmap.Save(path, imageFormat);
        }
    }
Oleneolenka answered 8/6, 2012 at 8:59 Comment(0)
F
3

Here is a small example that clarified a few things for me (I was struggling with this a bit too).

pBox is a PictureBox on Form1, make it at least 50x50

appPath was derived from System.Reflection but use any path you like

There are two buttons, one for drawing, one for saving, their click events are in the code below.

Things I learned:

(1) "pBox.Image =" doesn't do anything but initialize the pBox image, it DOES NOT have to be a filename as EVERY example I found used (had problem saving to that same file because it was share locked). Also, if your goal is to see things on the entire control's surface, you'll probably like setting the size at initialize time to the size you need. I used the pBox's size in this example but normally I use the bitmap size (because I typically begin with a real picture file).

(2) I always had problems either seeing my draws show up on the control or seeing my changes saved in the output file (or both). In my prior attempts I would duplicate the draws both on the control and on the bitmap. Of course that isn't necessary but the edited bitmap DOES need to be reloaded into the control.image... and THAT was the piece of this puzzle I was missing.

(A) Create a bitmap from the control.image and draw on the bitmap

(B) Load the bitmap into the control.Image (so you can see the changes caused by the draw)

(C) Save the control.Image

(2-option) You have a global (or passed) bitmap (probably from a real file)

(A) Draw on the bitmap

(B) Load the bitmap into the control.Image (so you can see the changes)

(C) Save the bitmap

    public Form1()
    {
        InitializeComponent();
        pBox.Image = new Bitmap(pBox.Width, pBox.Height);  
    }

    private void DrawStuff1_Click(object sender, EventArgs e)
    {
        Bitmap bmp = new Bitmap(pBox.Image);  
        Graphics g = Graphics.FromImage(bmp);

        g.FillRectangle(Brushes.Red, 5, 5, 25, 25); //hard-coded size to reduce clutter

        pBox.Image = bmp;  //this makes your changes visible
    }

    private void Save_Click(object sender, EventArgs e)
    {
        pBox.Image.Save(appPath + "SavedImage.bmp");
    }
Flagg answered 17/11, 2012 at 17:57 Comment(0)
V
1

You need paint to image of picture, not to the Graphics control on Paint event.

EDIT:

using( Graphics g = Graphics.FromImage( pictureBox1.Image ) ) {
    // there you will be do, what you do in Paint event
}

// ... somewhere else ...
pictureBox1.Save( _required_parameters_ );
Vertex answered 30/6, 2009 at 12:55 Comment(1)
Hi Can you clarify/give an example ?Cardona

© 2022 - 2024 — McMap. All rights reserved.