Question

I was loading a Bitmap Image from a File. When I tried to save the Image to another file I got the following error "A generic error occurred in GDI+". I believe this is because the file is locked by the image object.

Ok so tried calling the Image.Clone function. This still locks the file.

hmm. Next I try loading a Bitmap Image from a FileStream and load the image into memory so GDI+ doesn't lock the file. This works great except I need to generate thumbnails using Image.GetThumbnailImage method it throws an out of memory exception. Apparently I need to keep the stream open to stop this exception but if I keep the stream open then the file remains locked.

So no good with that method. In the end I created a copy of the file. So now I have 2 versions of the file. 1 I can lock and manipulate in my c# program. This other original file remains unlocked to which I can save modifications to. This has the bonus of allowing me to revert changes even after saving them because I'm manipulating the copy of the file which cant change.

Surely there is a better way of achieving this without having to have 2 versions of the image file. Any ideas?

Was it helpful?

Solution 2

I have since found an alternative method to clone the image without locking the file. Bob Powell has it all plus more GDI resources.

      //open the file
      Image i = Image.FromFile(path);

      //create temporary
      Image t=new Bitmap(i.Width,i.Height);

      //get graphics
      Graphics g=Graphics.FromImage(t);

      //copy original
      g.DrawImage(i,0,0);

      //close original
      i.Dispose();

      //Can now save
      t.Save(path)

OTHER TIPS

Well if you're looking for other ways to do what you're asking, I reckon it should work to create a MemoryStream, and read out the FileStream to it, and load the Image from that stream...

var stream = new FileStream("original-image", FileMode.Open);
var bufr = new byte[stream.Length];
stream.Read(bufr, 0, (int)stream.Length);
stream.Dispose();

var memstream = new MemoryStream(bufr);
var image = Image.FromStream(memstream);

Or something prettier to that extent.

Whether or not that's the way you should go about solving that problem, I don't know. :) I've had a similar problem and wound up fixing it like this.

I had a similar problem. But I knew, that I will save the image as a bitmap-file. So I did this:

    public void SaveHeightmap(string path)
    {
        if (File.Exists(path))
        {
            Bitmap bitmap = new Bitmap(image); //create bitmap from image
            image.Dispose(); //delete image, so the file

            bitmap.Save(path); //save bitmap

            image = (Image) bitmap; //recreate image from bitmap
        }
        else
            //...
    }

Sure, thats not the best way, but its working :-)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top