【问题标题】:A generic error occurred in GDI+ at System.Drawing.Image.SaveGDI+ 在 System.Drawing.Image.Save 中发生一般错误
【发布时间】:2014-05-07 15:19:33
【问题描述】:

例外:

GDI+ 中出现一般错误。 在 System.Drawing.Image.Save(字符串文件名,ImageCodecInfo 编码器,EncoderParameters 编码器参数) 在 System.Drawing.Image.Save(字符串文件名,ImageFormat 格式) 在 System.Drawing.Image.Save(字符串文件名)

代码:

byte[] bitmapData = new byte[imageText.Length];
MemoryStream streamBitmap;
bitmapData = Convert.FromBase64String(imageText);
streamBitmap = new MemoryStream(bitmapData);
System.Drawing.Image img = Image.FromStream(streamBitmap);
img.Save(path);

我们将 base64 字符串转换为 MemoryStream,然后创建 System.Drawing.Image (Image.FromStream(streamBitmap))。 最后,图像被保存在一个临时文件中。

奇怪的是,当 Web 服务器上的活动(并发用户数)很高并且在 IISRESET 或应用程序池回收后暂时解决了问题时,似乎会出现问题......

==> 垃圾收集器问题?

我已经检查了TEMP文件夹的权限...

【问题讨论】:

    标签: c# asp.net .net image gdi+


    【解决方案1】:

    此错误是由于图像已在使用中。无论您在哪里使用图像,都将图像转换为字符串 base 64 格式并使用它。这将解决错误。

    【讨论】:

      【解决方案2】:

      当您从流加载图像时,您必须在图像的生命周期内保持流打开,请参阅MSDN Image.FromStream

      我认为这个异常是因为内存流在图像被处理之前就关闭了。您可以像这样更改代码:

      byte[] bitmapData = new byte[imageText.Length];
      bitmapData = Convert.FromBase64String(imageText);
      
        using (var streamBitmap = new MemoryStream(bitmapData))
        {
            using (img = Image.FromStream(streamBitmap))
            { 
               img.Save(path);
            }
        }
      

      以下是讨论类似问题的线程的一些链接:

      gdi+ error saving image from webpage

      When drawing an image: System.Runtime.InteropServices.ExternalException: A generic error occurred in GDI

      【讨论】:

      • 好点,谢谢!我将实施此更改并进行进一步测试。
      • 添加此评论是因为有人删除了我与此已接受答案相关的补充答案。如果您看到 GDI 错误在一段时间后被抛出,这里是如何确认它正在泄漏导致异常的 GDI 内存。在程序泄露 10,000 个句柄后,Windows 将不再提供它。您可以使用 TaskMgr.exe 诊断此类泄漏 单击进程选项卡 右键单击​​列并选择列以添加 GDI 对象的列。如果 GDI 对象是稳定增长的对象 - 那么您就有 GDI 内存泄漏。
      【解决方案3】:

      当您调用“Image.FromFile”或“Image.Save”时,图像对象将锁定文件,直到它被显式释放。如果您对同一文件名执行另一个“Image.Save”或“Image.FromFile”,您可能会收到“一般错误”异常。这取决于垃圾收集器是否已经处理了图像,因此结果不一致。

      如果您在执行“保存”操作后不需要该图像,则应立即将其丢弃。如果您确实需要该图像,Image.Clone 将制作一个不会锁定源文件的副本。

      我在图像库编辑应用程序中遇到过这个问题,这是一个解决方案。

      【讨论】:

        【解决方案4】:

        在我的情况下,下面 sn-p 工作正常,其中 ConvertedImageString 是从 API 接收的 Base64Image 字符串,我将其转换为具有格式的相关图像并将其保存到服务器上的物理文件夹.

        编辑:出现上述错误可能是因为您尝试保存图像的文件路径错误

        string converted = ConvertedImageString.Replace('-', '+');
        converted = converted.Replace('_', '/');
        using (MemoryStream ms = new MemoryStream(Convert.FromBase64String(ConvertedImageString)))
        {
            using (Bitmap bm1 = new Bitmap(ms))
            {
                newFileName =  id + ".jpg";
                newFileName = CleanFileName(newFileName);
                newFileName = newFileName.Replace(" ", "_");
        
                Path = Path + newFileName;
        
                bm1.Save(Path, ImageFormat.Jpeg);
            }
        }
        

        【讨论】:

        • 在上面的代码中,我将图像作为图像的BASE64ConvertedString 并以“联合图像专家组”格式存储在 IIS 目录或网站目录中。就是这样。
        • 把这个放在你的答案中!
        【解决方案5】:

        确保您指定的路径有效。如果文件路径不存在,使用上一个答案(使用内存流上的使用),您仍然可能会收到这个确切的错误“GDI+ 中的通用错误”。文件将被创建,目录路径必须存在。

        【讨论】:

        • 这个对我很有帮助。就我而言,由于路径错误,引发了同样的错误。谢谢。
        【解决方案6】:

        我在保存图像时遇到了同样的异常消息。事实证明我的代码很好,并且在做它应该做的事情。

        问题是硬盘驱动器已满,因此无法创建新映像。我只是在尝试保存我正在处理的项目时才注意到这一点,因为它没有空间可以保存。

        【讨论】:

        • 在我的情况下,我的 IIS 应用程序池用户没有对该目录的写入权限。只是想在此处添加该注释,因为此答案是类似的问题。
        • 2015年如何让硬盘满载?
        猜你喜欢
        • 1970-01-01
        • 2014-09-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多