C# – Loading, saving, and then loading an image again throws “A generic error occurred in GDI+”

cgdi+image

This seems to be in infamous error. I remember getting it a while back for different code, but it's back, with a vengeance, but with some new code that I can't seem to figure out.
It's definitely generic, for sure!

The Goal

I'm trying to build a form that allows a user to:

  1. Select an image.
  2. Press save (which closes the form), and saves the image to a byte[] into a database.
  3. Open the form (which loads the image from the byte[]).
  4. Allow them to press save again.
  5. Allow them to open the form again, displaying the image (again).

A pretty standard load/save scenario.

The Problem

Everything works fine regarding loading and saving to the SQL Server. The problem I'm getting is to do with repeatedly loading and saving to and from a byte[] even though I'm using the same settings. Take a look at this code which I mocked up to demonstrate the problem:

static void Main(string[] args)
{
    // Load the image
    var initialImage = (Bitmap)Bitmap.FromFile(@"D:\picture.jpg");

    // Save to a memory stream and get the bytes
    var initialImageBytes = SaveImageToBytes(initialImage);

    // Load again from this saved image
    Bitmap byteLoadedImage = LoadImageFromBytes(initialImageBytes);

    // Save again to bytes, throws "A generic error occurred in GDI+."
    var secondaryImageBytes = SaveImageToBytes(byteLoadedImage);
}

private static byte[] SaveImageToBytes(Bitmap image)
{
    byte[] imageBytes;
    using (MemoryStream imageStream = new MemoryStream())
    {
        image.Save(imageStream, image.RawFormat);
        // "A generic error occurred in GDI+." thrown when saved second time
        imageBytes = imageStream.ToArray();
    }

    return imageBytes;
}

private static Bitmap LoadImageFromBytes(byte[] bytes)
{
    using (MemoryStream imageStream = new MemoryStream(bytes))
    {
        Bitmap image = (Bitmap)Bitmap.FromStream(imageStream);
        return image;
    }
}

The error A generic error occurred in GDI+. is thrown as the image is saved once more to the MemoryStream the second time round. I checked this wasn't to do with the RawFormat by inspecting the value before the first save, and before the second:

1st Save : {b96b3cae-0728-11d3-9d7b-0000f81ef32e}
2nd Save : {b96b3cae-0728-11d3-9d7b-0000f81ef32e}

The values are identical, so it can't be a problem with it losing the ImageFormat information.

Can anyone help debug this problem? The code sample I used is tested with a JPEG, and you can get it here.

Best Answer

I had what I believe was the same problem recently. You need to skip the using statement around the creation of your MemoryStream. Creating a bitmap keeps a reference to the stream that created it. You can read about it on MSDN.

private static Bitmap LoadImageFromBytes(byte[] bytes)
{
    var imageStream = new MemoryStream(bytes))
    var image = (Bitmap)Bitmap.FromStream(imageStream);
    return image;
}