【问题标题】:A Generic error occurs at GDI+ at Bitmap.Save() after using SaveFileDialog使用 SaveFileDialog 后在 Bitmap.Save() 处的 GDI+ 处发生一般错误
【发布时间】:2011-08-14 09:25:36
【问题描述】:

我在 using 块中使用了以下代码块和更多代码:

using (System.Drawing.Bitmap tempImg =
       (System.Drawing.Bitmap)tempObj.GetData(System.Windows.Forms.DataFormats.Bitmap))
{
    // ...
    tempImg.Save("..\\..\\testdata\\tempImg.bmp", ImageFormat.Bmp);                            
    // ...
}

但我仍然收到错误:

GDI+ 发生一般错误

只有在我做了一些与 using 块内的代码无关的操作之后。在其他时候,这很好用。 tempImg.bmp 也是一个临时文件,所以我在 using 块本身中删除了 tempImg.bmp。

由于 tempImg 在 using 中并且它已被处理,我认为应该解决锁定问题。

谁能告诉我这段代码有什么错误?

编辑: System.Drawing.ImageSystem.Drawing.Bitmap 作为tempImg 的类型。

编辑: 我已经确定只有在创建 SaveFileDialog 并且用户单击“保存”后才会收到此错误。

【问题讨论】:

  • 为什么 tempImg Image 和你的演员 Bitmap
  • 抱歉,应该更正为 SYStem.Drawing.Bitmap... 感谢您的评论
  • 只有在我做了一些与代码无关的操作后这是否涉及读取/保存其他图像?
  • 不,它只使用从 tempImg 获得的 Bitmap 对象创建一个 avi 文件,虽然每次获取 bitmap 对象后都会删除 using 块内的流本身t和 tempImg.bmp。
  • 所以这可能是问题,因为它已经被进程使用,发布该代码以便它更相关

标签: c# bitmap save savefiledialog


【解决方案1】:

我遇到了同样的问题,通过将图像类型“.bmp”更改为“.png”它的工作形式我

【讨论】:

    【解决方案2】:

    就我而言,我将位图文件保存在与源相同的位置, 所以这就是问题所在。 我将位图保存到新位置,现在一切正常。

    【讨论】:

      【解决方案3】:

      在我的例子中,它是一个 ASP.NET 应用程序,我在其中替换了一个 DLL,并且在部署后我必须简单地重新启动应用程序池。然后效果很好。

      【讨论】:

      • 这让我发疯了,尝试了其他帖子中说代码运行良好的所有内容,然后突然之间它不再给我们留下这个 gdi+ 错误。 IIS 在问题发生前一天重新启动,但应用程序池没有。重新启动应用程序池后一切都很好,谢谢 Fabian。
      【解决方案4】:

      保存图片后处理你的bitMap对象:

       bitMap.Dispose()
       oimg.Dispose()
      
       bitMap = Nothing
       oimg = Nothing
      

      【讨论】:

        【解决方案5】:

        我正在尝试从资源中保存图像,当我直接使用方法 Bitmap.Save(filepath) 时,它也给了我 GDI 错误。 我认为我们可以通过克隆它来对任何其他位图图像使用相同的以下代码。

        Private void SaveResourceImage() {
            object resBmpObject = Resource.Image1.Clone();//Bitmap Image from resource file
            //object resBmpObject = anyBmpImage.clone(); //for image other than resource image
            Bitmap resBmpImage = (Bitmap)resBmpObject;
            resBmpImage.Save(destFilePath, System.Drawing.Imaging.ImageFormat.Png);
            resBmpImage.dispose();
        }
        

        【讨论】:

          【解决方案6】:

          尝试了这里给出的所有解决方案,但徒劳无功。终于找到了解决办法。

          1. 处理应用于图像的任何图形:g.dispose();
          2. 确保存在保存路径:System.IO.Directory.Exists(dir);

          【讨论】:

            【解决方案7】:

            最后我可以找到我的代码中的错误并想在这里提及它,因为我认为它可能对某人有用....

            由于我在 tempImg.Save 中给出了相对路径,并且用户在 SaveFileDialog 中单击“保存”后,tempImg.Save 的实际路径变为:

            SaveFileDialog指定的路径+相对路径

            自动。

            因此如果路径不存在,就会出现这个错误。

            感谢每一位的回答。

            【讨论】:

            • 我忘记确保我的目录存在,并得到同样的错误。感谢分享!
            • 感谢这个有用的提示。我检查目录是否存在。没关系。 ;)
            • 是的,我遇到了这个问题,我的问题是我正在创建动态文件路径并且必须 Trim() 我的变量
            【解决方案8】:

            我也遇到过这个问题-它发生是因为位图锁定并且您无法保存它(如果您愿意,我可以找到确切的解释)所以无论如何解决方法是这样的: 创建一个与原始位图大小相同的新位图 - 将原始位图复制到新创建的位图,然后处理原始位图并保存新位图。

            Bitmap bm3 = new Bitmap(bm2);
            

            然后保存。

            【讨论】:

            • 谢谢!我不知道作者,但你的解决方案对我有用!
            • 谢谢,这绝对有帮助。但是,我必须添加一个 thread.sleep 以便操作系统有一些时间来释放任何资源。我不知道为什么。
            • 这对我有帮助。谢谢。
            【解决方案9】:

            这是来自 Microsoft 论坛的代码示例。

            // new image with transparent Alpha layer
            using (var bitmap = new Bitmap(330, 18, PixelFormat.Format32bppArgb))
            {
                using (var graphics = Graphics.FromImage(bitmap))
                {
                    // add some anti-aliasing
                    graphics.SmoothingMode = SmoothingMode.AntiAlias;
            
                    using (var font = new Font("Arial", 14.0f, GraphicsUnit.Pixel))
                    {
                        using (var brush = new SolidBrush(Color.White))
                        {
                            // draw it
                            graphics.DrawString(user.Email, font, brush, 0, 0);
                        }
                    }
                }
            
                // setup the response
                Response.Clear();
                Response.ContentType = "image/png";
                Response.BufferOutput = true;
            
                // write it to the output stream
                bitmap.Save(Response.OutputStream, ImageFormat.Png);
                Response.Flush();
            }
            

            【讨论】:

              【解决方案10】:

              这是一个 ASP.NET 应用程序吗?

              asp.net 中的 GDI+ 发生一般错误,主要是因为缺少目标文件夹/访问权限。

              您的代码也可以简化为:

                     using (Image image= dataObject.GetImage())
                     {
                          if (image != null)
                          {
                              image.Save("test.bmp");
                          }
                      }
              

              【讨论】:

              • 权限没有问题,因为除了我提到的一种情况外,所有情况下的过程都很顺利。谢谢
              【解决方案11】:

              这通常表明其他东西,可能是您自己的应用程序中的其他线程,已经将您尝试保存的目标文件锁定在文件系统级别。如果您查看内部异常,我相信它应该提到这一点。如果它不是直接在 InnerException 中确认这一点的另一种方法(或发现它可能实际上是什么)是在调试器中打开第一次机会异常并观察在“下方”抛出什么异常保存,然后变成这个一般异常。

              【讨论】:

              • tempImg 没有在代码中的任何地方使用,内部异常说:System.Drawing.dll 中发生了“System.Runtime.InteropServices.ExternalException”类型的第一次机会异常
              • 这很可能是这种情况,看看微软使用 GDI+ 的常见做法
              • ExternalException 具有 HResult/ErrorCode 属性。您能告诉我们该房产的价值是多少吗?这应该让我们找到 GDI+ 所遇到的确切的原生问题。
              • 是的,GDI+ 似乎是单线程的,我在尝试保存加载到另一个线程中的 System.Drawing.Image 时出错。修复正在保存new Bitmap(originalImage)
              猜你喜欢
              • 1970-01-01
              • 2011-01-26
              • 2017-05-04
              • 2010-12-20
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2012-11-14
              • 2014-05-07
              相关资源
              最近更新 更多