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

GDI+ exception when saving image in PNG format

我服务器上的一个 ASP.NET 应用程序在 运行ning 几天后开始抛出 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. 更多。

我觉得应该是什么配置突然变了,看不懂是什么东西

After I restart the server all works fine for a couple of days and then suddenly this exception occurs and after the first time it occurs it will occur everytime I try to save the PNG image, until I will restart again.

在我看来像是内存泄漏。这是编译成什么 .NET 版本?这个 运行 在哪个服务器 OS 上?

您可以先将图像包含在 using 块中:

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 我认为与您的情况相关。

它抛出 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
}

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