CodeSpeaker
CodeSpeaker

Reputation: 850

GDI+ error on Bitmap.Save

Ive managed to get something like this to work in another project but not on my current. The file locks and cannot be overwritten when saving again even though i dispose of the b bitmap before calling save. Any idea of what i might be doing wrong?

Bitmap b = (Bitmap)Image.FromFile("image.png");
Bitmap bClone = (Bitmap)b.Clone();

    // modify bClone here..

b.Dispose();
b = null;
GC.Collect();

bClone.Save("image.png");

Upvotes: 0

Views: 1091

Answers (3)

Gary L Smith
Gary L Smith

Reputation: 9

After many hours looking for a solution and trying different combinations, it appears that there is some issue of saving an image on a stale image. What am doing is creating a list of scanned documents, saving the scanned image as a PictureBox in a FlowLayoutPanel. That all works great, as I can click the various documents and they show up on a larger picture box. But when I tried to save the images by going through the FlowLayoutPlanel.Controls collection, I would get the GDI+ error on save.

What I ended up doing, while not elegant, but it does work, it to create a new bitmap and making sure I tell the save that it's a jpeg it's saving. Here is the code (vb.net 2022 - 17.8.7) that loops through the FlowLayoutPanel (imageCollection):

idx = 1
For Each pb As PictureBox In imageCollection.Controls
    Dim bmp = New Bitmap(pb.Image)
    bmp.Save(ClientDir & "\" & thisDoc.ClientDocumentID.ToString("D7") & "-" & idx.ToString("D2") & ".jpg", ImageFormat.Jpeg)

    idx += 1
Next

As far as not being able to save pb directly, who knows. But the data (.image) must be transferred to a new bitmap, so my guess it's a memory issue somewhere. Because the image is definitely there, as I can put it back into the larger PictureBox, and this code does save all of the images in the collection.

Upvotes: 0

David
David

Reputation: 34543

The "Clone" method doesn't do what you want. You can use the Bitmap's copy constructor instead to create a separate image that contains the same pixels.

Bitmap bClone = null;
using (Bitmap b = (Bitmap)Image.FromFile("image.png"))
{
    bClone = new Bitmap(b);
    // modify bClone here..
}

bClone.Save("image.png");
bClone.Dispose();

Upvotes: 1

Mark Ransom
Mark Ransom

Reputation: 308121

Using FromFile you really don't have any control over the lifetime of the file object. Try FromStream instead.

Upvotes: 0

Related Questions