简体   繁体   English

GDI+ 中的 System.Drawing.Image.Save 发生一般性错误

[英]A generic error occurred in GDI+ at System.Drawing.Image.Save

Exception:例外:

A generic error occurred in GDI+. GDI+ 中发生一般性错误。 at System.Drawing.Image.Save(String filename, ImageCodecInfo encoder, EncoderParameters encoderParams) at System.Drawing.Image.Save(String filename, ImageFormat format) at System.Drawing.Image.Save(String filename)在 System.Drawing.Image.Save(字符串文件名,ImageCodecInfo 编码器,EncoderParameters encoderParams)在 System.Drawing.Image.Save(字符串文件名,ImageFormat 格式)在 System.Drawing.Image.Save(字符串文件名)

Code:代码:

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);

We convert a base64 string into a MemoryStream and then create a System.Drawing.Image (Image.FromStream(streamBitmap)).我们将一个 base64 字符串转换为 MemoryStream,然后创建一个 System.Drawing.Image (Image.FromStream(streamBitmap))。 At the end the image is saved in a temp file.最后图像被保存在一个临时文件中。

The strange thing is that the problem seems to occur when the activity (number of concurrent users) is high on the web server and the problem is solved temporarily after an IISRESET or an application pool recycle...奇怪的是,问题似乎是在web服务器上的活动(并发用户数)很高时出现的,并且在IISRESET或应用程序池回收后问题暂时解决了......

==> Garbage collector issue? ==> 垃圾收集器问题?

I already checked the permission of the TEMP folder...我已经检查了 TEMP 文件夹的权限...

When you are loading an imagefrom a Stream, You have to keep the stream open for the lifetime of the image, see this MSDN Image.FromStream .当您从流加载图像时,您必须在图像的生命周期内保持流打开,请参阅此MSDN Image.FromStream

I think the exception is caused because the memory stream gets closed even before the image gets disposed.我认为这个异常是因为内存流在图像被处理之前就被关闭了。 You can change your code like this:您可以像这样更改代码:

byte[] bitmapData = new byte[imageText.Length];
bitmapData = Convert.FromBase64String(imageText);

  using (var streamBitmap = new MemoryStream(bitmapData))
  {
      using (img = Image.FromStream(streamBitmap))
      { 
         img.Save(path);
      }
  }

Here are some links to threads discussing similar problems:以下是一些讨论类似问题的线程的链接:

gdi+ error saving image from webpage gdi+ 从网页保存图像时出错

When drawing an image: System.Runtime.InteropServices.ExternalException: A generic error occurred in GDI 绘制图像时:System.Runtime.InteropServices.ExternalException:GDI 中发生一般错误

Make sure that the path you specified is valid.确保您指定的路径有效。 Using the previous answer (with the usings on the memory stream) you may still get this exact error "Generic Error in GDI+" if the file path does not exist.如果文件路径不存在,使用之前的答案(使用内存流),您可能仍然会收到此确切错误“GDI+ 中的通用错误”。 The file will be created, the directory path must exist.将创建文件,目录路径必须存在。

I encountered the same exception message when saving an image.我在保存图像时遇到了相同的异常消息。 It turned out my code was fine and doing what it was supposed to do.结果证明我的代码很好,并且做了它应该做的事情。

The problem was that the hard drive was full, thus the new image couldn't be created.问题是硬盘已满,因此无法创建新映像。 I only noticed this when trying to save the project I was working on, as it didn't have space to save.我只是在尝试保存我正在处理的项目时注意到这一点,因为它没有空间可以保存。

In my case, Below snippet works fine where ConvertedImageString is Base64Image string received from API and I convert that into a related image with a format and will save it to a physical file folder on Server.在我的情况下,下面的代码片段工作正常,其中ConvertedImageString是从 API 接收的 Base64Image 字符串,我将其转换为具有某种格式的相关图像,并将其保存到服务器上的物理文件夹中。

Edit: The above error occurs might be because of wrong file path on which you are trying to Save image编辑:发生上述错误可能是因为您尝试保存图像的文件路径错误

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);
    }
}

When you call "Image.FromFile" or "Image.Save" the image object will hold a lock on the file until it is explicitly disposed.当您调用“Image.FromFile”或“Image.Save”时,图像对象将锁定文件,直到它被明确释放。 If you perform another "Image.Save" or "Image.FromFile" on the same filename, you may get the "generic error" exception.如果您对相同的文件名执行另一个“Image.Save”或“Image.FromFile”,您可能会收到“通用错误”异常。 It depends on whether the garbage collector has disposed the image, so the results are inconsistent.这取决于垃圾收集器是否已经处理了图像,因此结果不一致。

If you don't need the image after a "Save" action, you should immediately dispose it.如果在“保存”操作后不需要该图像,则应立即处理它。 If you do need the image, Image.Clone will make a copy which does not hold a lock on the source file.如果您确实需要该图像,Image.Clone 将制作一个不锁定源文件的副本。

I have experienced this problem in an Image Library Editing application, and this was a solution.我在 Image Library Editing 应用程序中遇到过这个问题,这是一个解决方案。

I was getting this error because the folder I was trying to save the image to, did not exist .我收到此错误是因为我尝试将图像保存到的文件夹不存在 And image.Save(string path) , does not create the folder automatically.并且image.Save(string path)不会自动创建文件夹。 So this is something you have to create the folder programatically所以这是你必须以编程方式创建文件夹的东西

if (Directory.Exists(folderToUpload) == false)
{
    Directory.CreateDirectory(folderToUpload);
}

Then you should be able to save the image to desired location.然后您应该能够将图像保存到所需位置。

This error is due to the image is already in use.此错误是由于图像已在使用中。 Wherever you use the image convert the image into string base 64 format and use it.无论您在何处使用图像,都将图像转换为字符串 base 64 格式并使用它。 This will resolve the error.这将解决错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM