A generic error occurred in GDI+, for random images

The questions in SO, for example this one or this one have discussed many reason for this exception, but none could help me to find out my problem, and I still cannot figure out why this is happening.

I'm having this error, when trying to save (code is below). And the strangest thing I've got is that - this error is occurring for random images (let's say "random" for now, because I don't know exact problem yet). Only for particular images, out of thousands, I got this problem.

Here is the one successful and one unsuccessful image when trying.

1. 2009-05-23_00.51.39.jpg

  • Image dimensions: 768x1024

  • Size: 87KB

  • Bit depth: 24

  • Color representation: sRGB

2. 2009-05-23_00.52.50.jpg

  • Image dimensions: 768x1024

  • Size: 335KB

  • Bit depth: 24

  • Color representation: sRGB

For image #1 the process is going smoothly, with no errors. However, for image #2, I keep getting this error. As you see the images are almost the same. Both are .jpg, same dimensions, and most of the properties are just same.

Here is the method.

public static Stream GetImageBytes(Stream fileStream, int maxWidth, int maxHeight, bool showCopyRight, string link, int fillColor = 0xFFFFFF) 
{
    var img = Image.FromStream(fileStream);

    if (maxHeight != 0 && img.Height > maxHeight)
        ResizeByHeight(ref img, maxHeight, fillColor.ToString("X6"));

    if (maxWidth != 0 && img.Width > maxWidth)
        ResizeByWidth(ref img, maxWidth, fillColor.ToString("X6"));

    if (showCopyRight)
        img = ApplyWatermark(ref img, "watermark.png", link);

    var ms = new MemoryStream();

    //problem is here
    img.Save(ms, ImageFormat.Jpeg);
    img.Dispose();
    return ms;
}

Edit after comments.

Ok, here is the Watermark method

private static Bitmap ApplyWatermark(ref Image img, string watermarkPathPng, string link) {
        const int x = 0;
        var y = img.Height - 20;
        string watermarkText;
        if (img.Width <= 220) {
            watermarkText = "shorter copy";
        } else {
            if (img.Width < 500)
                watermarkText = "longer copy";
            else
                watermarkText = "full copy  " + link;
        }
        var bp = new Bitmap(img);
        img.Dispose();
        using (var gr = Graphics.FromImage(bp)) {
            var watermark = Image.FromFile(watermarkPathPng);
            gr.DrawImage(watermark, x, y, watermark.Width, watermark.Height);
            watermark.Dispose();
            gr.DrawString(watermarkText, new Font(new FontFamily("Batang"), 13, FontStyle.Regular, GraphicsUnit.Pixel), Brushes.Black, 5, y + 5);
        }
        return bp;
    }

The reason why I've used Bitmap inside this method is that I had Indexed Pixels problem before and that solved the issue.

Answers


Try copying the image rather than operating directly on the one you loaded. Often gdi errors are caused by you trying to change something that you think you "own" when the loader thinks it owns it.

As it only happens for some images, check the logic in your three processing methods - perhaps the failure only occurs if you need to do a vertical resize, in which case look for a bug in that method. Our maybe it's images that have to be processed by more than one of your methods.

It is also suspicious that you return img and pass it by reference in ApplyWatermark(). Check your logic here.


As I've not a great knowledge of GDI+, I'm not fully sure what has happened, but changing the following code line:

var ms = new MemoryStream();

//problem is here
img.Save(ms, ImageFormat.Jpeg);
img.Dispose();
return ms;

to this,

var ms = new MemoryStream();
var bit = new Bitmap(img);
img.Dispose();
bit.Save(ms, ImageFormat.Jpeg);
bit.Dispose();
return ms;

Worked well, so I just create a Bitmap from the image, then save the Bitmap to the Memory. Now this function is working well for all the images.


Need Your Help

C++ structures and chars

c++ struct structure

so, i have this code. i have some questions about it, im at the beggining of learning c++.

Property additionalActions of NSUserNotification seems not working?

swift cocoa nsusernotification

To understand NSUserNotification better, I wrote a little test app playing with this class.