简体   繁体   中英

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

Exception:

A generic error occurred in 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)

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

==> Garbage collector issue?

I already checked the permission of the TEMP folder...

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 .

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

When drawing an image: System.Runtime.InteropServices.ExternalException: A generic error occurred in 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. 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.

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. If you perform another "Image.Save" or "Image.FromFile" on the same filename, you may get the "generic error" exception. 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.

I have experienced this problem in an Image Library Editing application, and this was a solution.

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. 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. This will resolve the error.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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