I have a problem in a Windows Forms application with Bitmap.Save failing when I save to a MemoryStream. The problem only seems to occur intermittently on one machine (so far) and the bad news it is at a customer site. I can't debug on the machine, but I got a stack trace that narrowed the problem down to a single line of code.
Here's a condensed version of my code:
byte[] ConvertPixelsToBytes()
{
// imagine a picture class that creates a 24 bbp image, and has
// a method to get an unmanaged pixel buffer.
// imagine it also has methods for getting the width,
// height, pitch
// I suppose this line could return a bad address, but
// I would have expected that the Bitmap constructor would have
// failed if it was
System.IntPtr pPixels = picture.GetPixelData();
System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(
picture.width(),
picture.height(),
picture.pitch(),
System.Drawing.Imaging.PixelFormat.Format24bppRgb,
pPixels );
// This line doesn't actually free the memory, but it could be freed in a
// background thread
// (2)
picture.releasePixelData(pPixels);
System.IO.MemoryStream memStream = new System.IO.MemoryStream();
try
{
// I don't see how this line could fail, but it does
// (3)
bmp.Save(memStream, System.Drawing.Imaging.ImageFormat.Bmp);
return memStream.ToArray();
}
catch(System.Runtime.InteropServices.ExternalException e)
{
// e.Message is the very helpful " A generic error occurred in GDI+."
}
finally
{
memStream.Dispose();
}
return new byte[0];
}
Any idea what might be going on? I'm pretty sure my pixel buffer is right, it always works on our dev/test machines and at other customer sites.
My thoughts on possible reasons for failure are
a. The bitmap constructor doesn't copy the pixel data, but keeps a reference to it, and the Save fails because the memory is released. I don't find the MSDN docs clear on this point, but I assume that the Bitmap copies the pixel data rather than assume it is locked.
b. The pixel data is invalid, and causes the Save method to fail. I doubt this since my pixel data is 24 Bits per pixel, so as far as I know it should not be invalid.
c. There's a problem with the .NET framework.
I would appreciate any thoughts on other possible failure reasons so I can add extra checks and logging information to my app so I can send something out into the field.