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

C# 使用GDI+;将修改后的图像保存到原始文件;,c#,gdi+,image-manipulation,C#,Gdi+,Image Manipulation,我正在从文件中加载位图图像。当我试图将图像保存到另一个文件时,我遇到了以下错误“GDI+中发生了一般错误”。我相信这是因为文件被图像对象锁定了 好的,所以尝试调用Image.Clone函数。这仍然会锁定文件 嗯,接下来我尝试从文件流加载位图图像,并将图像加载到内存中,这样GDI+就不会锁定该文件。这非常有效,除了我需要使用Image.GetThumbnailImage方法生成缩略图外,它会引发内存不足异常。显然,我需要保持流打开以停止此异常,但如果我保持流打开,则文件保持锁定 所以用这种方法没有

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

好的,所以尝试调用Image.Clone函数。这仍然会锁定文件

嗯,接下来我尝试从文件流加载位图图像,并将图像加载到内存中,这样GDI+就不会锁定该文件。这非常有效,除了我需要使用Image.GetThumbnailImage方法生成缩略图外,它会引发内存不足异常。显然,我需要保持流打开以停止此异常,但如果我保持流打开,则文件保持锁定

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


当然,有一种更好的方法可以实现这一点,而不必有两个版本的图像文件。有什么想法吗?

如果你正在寻找其他方法来实现你的要求,我认为创建一个MemoryStream应该是可行的,然后将文件流读取到其中,然后从该流加载图像

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);
或者更漂亮的东西

我不知道你是否应该这样来解决这个问题
我也遇到过类似的问题,最后就这样解决了。

我找到了一种替代方法,可以在不锁定文件的情况下克隆图像


我也有类似的问题。但我知道,我会将图像保存为位图文件。所以我这样做了:

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

当然,这不是最好的方法,但它很有效:-)

太棒了。成功了。我的想法是对的,一旦完成,我就必须同时处理图像和内存流。仅处理图像仍会留下内存流?
    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
            //...
    }