如何在保存图像时找到Generic GDI +错误的原因?

拥有一个在加载和存储图像时可以使用多年的代码,我发现我有一个图像打破了这段代码:

const string i1Path = @"c:\my\i1.jpg"; const string i2Path = @"c:\my\i2.jpg"; var i = Image.FromFile(i1Path); i.Save(i2Path, ImageFormat.Jpeg); 

例外是:

发生了System.Runtime.InteropServices.ExternalException

GDI +中发生了一般错误。

在System.Drawing.Image.Save(String filename,ImageCodecInfo encoder,EncoderParameters encoderParams)
在System.Drawing.Image.Save(String filename,ImageFormat格式)
在 …

据我所知,图像并没有什么特别之处。 它的大小约为250像素,可以在Windows Image Viewer或Paint.NET中打开:

在此处输入图像描述

(由于上面的图片,在上传到Stack Overflow之后不再产生错误,我把原始图像放在这里 )

我发现在调用Save方法时 ,目标图像文件是用零字节创建的。

我真的对导致错误的原因一无所知。

我的问题:

  • 你能想到任何阻碍.NET保存图像的特殊事物吗?
  • 有没有办法(除了惊慌失措)缩小这些错误?

虽然我仍然没有找到保存图像时确切导致错误的原因,但我找到了一个适用的解决方法:

 const string i1Path = @"c:\my\i1.jpg"; const string i2Path = @"c:\my\i2.jpg"; var i = Image.FromFile(i1Path); var i2 = new Bitmap(i); i2.Save(i2Path, ImageFormat.Jpeg); 

即,通过将图像内部复制到Bitmap实例并保存此图像而不是原始图像,错误消失了。

我假设通过复制它,导致原始Save调用失败的错误部分被删除和/或标准化,从而使保存操作成功。

保存的图像i2.jpg

有趣的是,如此存储的图像在磁盘上的文件(16 kB)比原始文件(26 kB)小。

首先确保所需的文件夹具有读/写权限。 更改权限为我解决了这个问题。

解决方案在这里,您必须配置图像对象以释放服务器上的内存。 尝试使用using语句。 确保服务器上的目标目录也存在。

我的解决方案是在保存文件之前编写临时内容(File.WriteAllText)

这是代码:

 var i = Image.FromFile(i1Path); File.WriteAllText(i2Path, "empty"); // <---- magic goes here i.Save(i2Path, ImageFormat.Jpeg); 

请尝试让我知道

原因可能是图像被懒惰加载,并且当您尝试保存时,加载过程尚未完成。

按照本博文中的说法(假设您在问题中链接的图片为德语)提供了一种可能的解决方案。 此SO问题的接受答案表明这是由于您尝试保存的图像文件被锁定的事实。

编辑
对于Ulysses Alves,来自链接的博客条目:如果使用Image.FromFile()加载图像,它将保持锁定状态,直到它被处理掉。 这可以防止调用Save()

 pictureBox1.Image = Image.FromFile("C:\\test\\test1.jpg"); pictureBox1.Image.Save("C:\\test\\test2.jpg"); 

上面的代码抛出了一个错误。

要使其工作,您需要复制图像。 以下代码有效:

 pictureBox1.Image = Image.FromFile("C:\\test\\test1.jpg"); Image copy = pictureBox1.Image; copy.Save("C:\\test\\test2.jpg") 

在程序中打开

 const string i1Path = @"c:\my\i1.jpg"; const string i2Path = @"c:\my\i2.jpg"; var i = Image.FromFile(i1Path); i.Save(i2Path, ImageFormat.Jpeg); i.Dispose();