使用GDI +将修改后的图像保存到原始文件

时间:2020-12-05 16:03:12

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.

我正在从文件加载位图图像。当我试图将图像保存到另一个文件时,我收到以下错误“GDI +中发生了一般错误”。我相信这是因为文件被图像对象锁定。

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

好吧,试着调用Image.Clone函数。这仍然会锁定文件。

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.

哼。接下来,我尝试从FileStream加载位图图像并将图像加载到内存中,这样GDI +就不会锁定文件。这很好用,除了我需要使用Image.GetThumbnailImage方法生成缩略图,它抛出一个内存不足的异常。显然我需要保持流打开以停止此异常,但如果我保持流打开,则文件保持锁定状态。

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.

这种方法没有用。最后,我创建了该文件的副本。所以现在我有2个版本的文件。 1我可以在我的c#程序中锁定和操作。这个其他原始文件保持解锁状态,我可以保存修改。这样可以让我即使在保存后也可以恢复更改,因为我正在操作无法更改的文件副本。

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

当然,有一种更好的方法来实现这一点,而无需拥有2个版本的图像文件。有任何想法吗?

3 个解决方案

#1


2  

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...

好吧,如果你正在寻找其他方法来做你所要求的,我认为它应该工作创建一个MemoryStream,并读取它的FileStream,并从该流加载图像...

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.

不管你是否应该解决这个问题,我不知道。 :)我遇到了类似的问题,最终解决了这个问题。

#2


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.

我已经找到了一种替代方法来克隆图像而不锁定文件。鲍勃鲍威尔拥有这一切以及更多的GDI资源。

      //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)

#3


1  

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 :-)

当然,这不是最好的方式,但它的工作:-)

#1


2  

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...

好吧,如果你正在寻找其他方法来做你所要求的,我认为它应该工作创建一个MemoryStream,并读取它的FileStream,并从该流加载图像...

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.

不管你是否应该解决这个问题,我不知道。 :)我遇到了类似的问题,最终解决了这个问题。

#2


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.

我已经找到了一种替代方法来克隆图像而不锁定文件。鲍勃鲍威尔拥有这一切以及更多的GDI资源。

      //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)

#3


1  

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 :-)

当然,这不是最好的方式,但它的工作:-)