尝试使用Image.Save时出现“GDI+中发生通用错误”。

7

我正在开发一个Outlook 2010的插件,从一个序列化的XML文件中加载一张图片。图片可以很好地加载,并且可以轻松将其分配给Winform上的pictureBox对象。该对象保存在

[XmlIgnore]
public Bitmap Image
{
   get { return this.templateImage; }
   set { this.templateImage = value; }
 }

当我尝试将物理文件保存到硬盘上时,我正在执行以下操作:

string filePath = Path.Combine(dirPath, item.Id + ".jpg");
try
{
    item.Image.Save(filePath, System.Drawing.Imaging.ImageFormat.Jpeg);
}
catch (Exception e)
{
    Debug.WriteLine("DEBUG::LoadImages()::Error attempting to create image::" + e.Message);
}

我遇到了一个名为"GDI+"的通用错误。我已经检查了文件夹的写入权限,并且确保它有写入权限,但我不确定出了什么问题。我还尝试将ImageFormat更改为bmp、png等格式,以查看是否存在转换问题...但是没有效果。请问有谁能提供一些解决方法吗?


4
这个错误有很多可能的原因...非常令人沮丧。尝试以下几点:1)写入不同的文件夹。2)检查文件的尺寸。如果它太大(在4000x4000的范围内),也会引发此错误。3)确保文件没有被其他任何东西使用(包括您的代码)。 - Simon Whitehead
@Simon Whitehead,感谢您的建议。我尝试过写入父目录,也尝试了C:\temp,但都没有成功。该文件的尺寸为64x64像素(较小)。#3是我还没有尝试过的。我想我可以将图像复制到一个新对象中并尝试写入那个对象。稍后会报告结果。 - Magnum
@Simon Whitehead 已经解决了!问题在于我的代码使用 item 进行迭代,因此 GDI+ 似乎无法在完成后处理它。 - Magnum
6个回答

28

感谢Simon Whitehead在评论中的回答。他说,“3)确保文件没有被其他任何东西(包括您的代码)使用。”

因此,问题是我的代码正在使用item.Image对象,并且阻止GDI +调用其dispose()方法。 解决方法是将对象复制到新对象中,然后使用该对象进行“写入”。 生成的代码如下:

try
{
   using (Bitmap tempImage = new Bitmap(item.Image)) 
   {
      tempImage.Save(filePath, System.Drawing.Imaging.ImageFormat.Png);
   }    
}
catch (Exception e)
{
    Debug.WriteLine("DEBUG::LoadImages()::Error attempting to create image::" + e.Message);
}

3
仍然没有解决问题,你必须处理 tempImage 以释放文件的锁定。使用 using 语句。 - Hans Passant
@HansPassant 谢谢,我修改了我的答案以反映您的评论。 - Magnum
非常感谢!这就是我遇到问题的原因。在using块中创建一个新的Bitmap对象解决了我的问题。 - Richard Powell

8

我也遇到了与以下代码行相关的相同错误:

wmImg.Save(BrandImgPath,ImageFormat.Png);

BrandImgPath = "D:/XYZ/fileName;

发现原因:

在D盘中不存在XYZ文件夹。因此,我的代码稍后会创建此文件夹。应确保该路径是否存在。

if (Directory.Exists(@"D:/XYZ")) return;

希望这篇文章能帮助某些人解决他们的代码错误。


4


1. 确保目标文件夹有读写权限(检查两次!)
2. 使用 Server.MapPath 更好
3. 确保您的目标驱动器或文件夹上有足够的可用空间。
4. 大多数情况下,我们不能在共享服务器上使用内存流,所以我们应该确保提供商允许我们使用它。

希望微软能提供详细的异常错误提示,而不是“通用 GDI+ 错误”!!!


1
我自己也遇到了这个问题,需要检查文件夹是否存在,GDI没有告诉我出了什么问题,如果有提示就好了。

0

我曾经遇到过相同的通用异常,但是在平行 Plesk 文件管理器上给了 IIS 写入权限后问题得以解决。如果你使用的是 Windows 服务器,请确保给予 IIS 用户写入权限,我的服务器上是 IIS_IUSR。

同时,请确保你尝试保存的文件夹与上述评论中提到的正确。


0
在我的情况下,出现了一个拼写错误,导致我保存图像的路径不正确:
if (Directory.Exists(directory_path))
{
 image.SaveAs(directory_path + filename);
}

如 gaffleck所说,如果GDI+能够抛出更多详细的异常信息就好了。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接