A generic error occurred in GDI+, JPEG Image to MemoryStream

前端 未结 30 1376
再見小時候
再見小時候 2020-11-22 06:47

This seems to be a bit of an infamous error all over the web. So much so that I have been unable to find an answer to my problem as my scenario doesn\'t fit. An exception ge

相关标签:
30条回答
  • 2020-11-22 07:16

    Had a very similar problem and also tried cloning the image which doesn't work. I found that the best solution was to create a new Bitmap object from the image that was loaded from the memory stream. That way the stream can be disposed of e.g.

    using (var m = new MemoryStream())
    {
        var img = new Bitmap(Image.FromStream(m));
        return img;
    }
    

    Hope this helps.

    0 讨论(0)
  • 2020-11-22 07:16

    In my case the problem was in the path I was saving (the root C:\). Changing it to D:\111\ made the exception go away.

    0 讨论(0)
  • 2020-11-22 07:16

    Another cause for this error - the path you indicate in the Save method of the Bitmap instance doesn't exist or you haven't supplied a full / valid path.

    Just had this error because I was passing in a filename and not a full path!

    It happens!

    0 讨论(0)
  • 2020-11-22 07:18

    You'll also get this exception if you try to save to an invalid path or if there's a permissions issue.

    If you're not 100% sure that the file path is available and permissions are correct then try writing a to a text file. This takes just a few seconds to rule out what would be a very simple fix.

    var img = System.Drawing.Image.FromStream(incomingStream);
    
    // img.Save(path);
    System.IO.File.WriteAllText(path, "Testing valid path & permissions.");
    

    And don't forget to clean up your file.

    0 讨论(0)
  • 2020-11-22 07:19

    I also got this error when saving JPEGs, but only for certain images.

    My final code:

      try
      {
        img.SaveJpeg(tmpFile, quality); // This is always successful for say image1.jpg, but always throws the GDI+ exception for image2.jpg
      }
      catch (Exception ex)
      {
        // Try HU's method: Convert it to a Bitmap first
        img = new Bitmap(img); 
        img.SaveJpeg(tmpFile, quality); // This is always successful
      }
    

    I didn't create the images so I can't tell what the difference is.
    I'd appreciate if anyone could explain that.

    This is my SaveJpeg function just FYI:

    private static void SaveJpeg(this Image img, string filename, int quality)
    {
      EncoderParameter qualityParam = new EncoderParameter(Encoder.Quality, (long)quality);
      ImageCodecInfo jpegCodec = GetEncoderInfo("image/jpeg");
      EncoderParameters encoderParams = new EncoderParameters(1);
      encoderParams.Param[0] = qualityParam;
      img.Save(filename, jpegCodec, encoderParams);
    }
    
    private static ImageCodecInfo GetEncoderInfo(string mimeType)
    {
        var encoders = ImageCodecInfo.GetImageEncoders();
        var encoder = encoders.SingleOrDefault(c => string.Equals(c.MimeType, mimeType, StringComparison.InvariantCultureIgnoreCase));
        if (encoder == null) throw new Exception($"Encoder not found for mime type {mimeType}");
        return encoder;
    }
    
    0 讨论(0)
  • 2020-11-22 07:20

    This is an expansion / qualification of Fred's response which stated: "GDI limits the height of an image to 65534". We ran into this issue with one of our .NET applications, and having seen the post, our outsourcing team raised their hands in the air and said they couldn't fix the problem without major changes.

    Based on my testing, it's possible to create / manipulate images with a height larger than 65534, but the issue arises when saving to a stream or file IN CERTAIN FORMATS. In the following code, the t.Save() method call throws our friend the generic exception when the pixel height is 65501 for me. For reasons of curiosity, I repeated the test for width, and the same limit applied to saving.

        for (int i = 65498; i <= 100000; i++)
        {
            using (Bitmap t = new Bitmap(800, i))
            using (Graphics gBmp = Graphics.FromImage(t))
            {
                Color green = Color.FromArgb(0x40, 0, 0xff, 0);
                using (Brush greenBrush = new SolidBrush(green))
                {
                    // draw a green rectangle to the bitmap in memory
                    gBmp.FillRectangle(greenBrush, 0, 0, 799, i);
                    if (File.Exists("c:\\temp\\i.jpg"))
                    {
                        File.Delete("c:\\temp\\i.jpg");
                    }
                    t.Save("c:\\temp\\i.jpg", ImageFormat.Jpeg);
                }
            }
            GC.Collect();
        }
    

    The same error also occurs if you write to a memory stream.

    To get round it, you can repeat the above code and substitute ImageFormat.Tiff or ImageFormat.Bmp for ImageFormat.Jpeg.

    This runs up to heights / widths of 100,000 for me - I didn't test the limits. As it happens .Tiff was a viable option for us.

    BE WARNED

    The in memory TIFF streams / files consume more memory than their JPG counterparts.

    0 讨论(0)
提交回复
热议问题