以PNG格式保存图像时出现GDI +异常

时间:2016-08-31 21:33:17

标签: c# asp.net-mvc image iis gdi+

我的服务器上的ASP.NET应用程序在运行几天后开始抛出GDI +异常。重新启动服务器后,所有工作正常几天,然后突然再次发生此异常。第一次发生后,每次我尝试保存PNG图像时都会发生,直到我重新开始。

当我尝试以JPEG格式保存图像时,它可以正常工作。

当我从项目中运行此代码时,它失败了:

var path = @"C:\Project\images\logo.png";
var image = Image.FromFile(path);

using (var ms = new MemoryStream())
{
    image.Save(ms, ImageFormat.Png);     // Fails here on GDI+ exception.
    //image.Save(ms, ImageFormat.Jpeg);  // JPEG works somehow
}

再次:当我重新启动远程桌面并运行此代码时,它会工作几天,并且在某个时刻突然开始一次又一次地失败。

我试过了:

  1. 使用相同的代码创建一个控制台应用程序,并在项目所在的RDP中运行它。它工作得很好!

  2. 我在这个主题上阅读的10多篇文章中提出了很多不同的代码变体。

  3. GCI.Collect() - 没有帮助。

  4. 检查了所有具有写入权限的文件夹(可能是IIS有什么内容?)。

  5. 更多。

  6. 我认为它应该是一些突然因某些东西而改变的配置,我无法理解它是什么。

3 个答案:

答案 0 :(得分:9)

  

重新启动服务器后,所有工作正常几天,然后突然发生此异常,并且在第一次发生后,每次我尝试保存PNG图像时都会发生这种情况,直到我重新启动。

听起来像是内存泄漏给我。这个编译的.NET版本是什么?这个运行的服务器操作系统是什么?

您可以将图像封闭在使用块中:

var path = @"C:\Project\images\logo.png";
using (Image image = Image.FromFile(path))
{
    using (var ms = new MemoryStream())
    {
        image.Save(ms, ImageFormat.Png);
    }
}

This link我认为与您的案件相关。

答案 1 :(得分:3)

因为你的对象没有被处理而抛出GDI +错误,所以最好处置使用过的对象。

如果您收到该错误,那么我可以说您的应用程序没有某个目录的写入权限。

GDI +将图片的高度限制为65534

始终倾向于使用 using语句。即使代码抛出异常,也永远不会忘记处理对象。

var path = @"C:\Project\images\logo.png";
using (Image image = Image.FromFile(path))
{
      using (var ms = new MemoryStream())
      {
            image.Save(ms, ImageFormat.Png); //fails here on GDI+ exception.
            //image.Save(ms, ImageFormat.Jpeg); //Jpeg Works somehow
      }
}

FromFile方法锁定文件,因此请使用Image.FromStream()方法读取图像:

byte[] bytes = System.IO.File.ReadAllBytes(filename);
System.IO.MemoryStream ms = new System.IO.MemoryStream(bytes);
using (var ms = new MemoryStream())
{
      image.Save(ms, ImageFormat.Png); //fails here on GDI+ exception.
      //image.Save(ms, ImageFormat.Jpeg); //Jpeg Works somehow
}

答案 2 :(得分:0)

基本上,如果你有一次性物品......请处理它们! 图像是一次性的,就像位图一样,它使用Windows资源。 如果不进行处理,则在关闭应用程序之前不会释放Windows资源。所以你需要处理任何实例化的图像。