Consider this code for loading, modifying and saving a Bitmap image:
using (Bitmap bmp = new Bitmap("C:\\test.jpg"))
{
bmp.RotateFlip(RotateFlipType.Rotate180FlipNone);
bmp.Save("C:\\test.jpg");
}
it runs without any exception. But consider this one:
using (Bitmap bmp = new Bitmap("C:\\test.jpg"))
{
using (Bitmap bmpClone = (Bitmap)bmp.Clone())
{
//You can replace "bmpClone" in the following lines with "bmp",
//exception occurs anyway
bmpClone.RotateFlip(RotateFlipType.Rotate180FlipNone);
bmpClone.Save("C:\\test.jpg");
}
}
It ends in an ExternalException with this message: "A generic error occurred in GDI+". What's wrong here? Any kind of lock on opened file? If so, why the first block works? What is the proper code for cloning a System.Drawing.Bitmap while we may need to edit main object or its clone in the memory and still have them both loaded in memory?
Yes, the file is locked when the first bitmap object is loaded and thus bmpClone.Save()
to the same file fails because you have a logical deadlock.
When opening Bitmaps by filename, the file is locked throughout the life of the Bitmap. If you use a stream, the stream must remain open.
Update:
If you wish to have two bitmaps in memory for use outside of the scope of the method you are in, then you won't be using a using
block.
Create the first image from file, and then clone it. Utilize them as needed throughout your UI lifecycle but make sure you clean them up using Dispose()
when they are no longer needed so that underlying resources are released.
Also, from MSDN:
Saving the image to the same file it was constructed from is not allowed and throws an exception
That's pretty awkward. If the object created using clone()
keeps information on the image source (e.g. a handle on the original file) or you can't otherwise unlock the file while using the Bitmap instances, then you'll probably have to either save to a new file, or open from a temporary copy of the original.
Try this instead:
// ... make a copy of test.jpg called test_temp.jpg
Bitmap bmpOriginal = new Bitmap("C:\\test_temp.jpg"))
Bitmap bmpClone = (Bitmap)bmp.Clone();
// ... do stuff
bmpClone.RotateFlip(RotateFlipType.Rotate180FlipNone);
bmpClone.Save("C:\\test.jpg");
// ... cleanup
bmpOriginal.Dispose();
bmpClone.Dispose();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With