Save bitmap to file has zero in image size field

2k views Asked by At

I find when I use the Bitmap.Save method with format ImageFormat.Bmp that the bitmap header info in the file has zero in the biSizeImage field.

From what I can see this is ok according to the specs, but unfortunately the crappy embedded device I am forced to work with insists on it being set correctly.

So the question is how to go about getting this header info field always set when the bitmap is saved?

2

There are 2 answers

2
Cody Gray - on strike On BEST ANSWER

The issue, as you suspect, is that 0 is a perfectly allowable value for the image size field of an RGB bitmap. The MSDN documentation for the BITMAPINFOHEADER structure confirms this fact:

biSizeImage
The size, in bytes, of the image. This may be set to zero for BI_RGB bitmaps.

If biCompression is BI_JPEG or BI_PNG, biSizeImage indicates the size of the JPEG or PNG image buffer, respectively.

So the implementation in the .NET Framework is simply doing things the standard, documented way. Since you need something else, you'll have to handle the save to file process yourself, which will allow you to manually modify the biSizeImage member of the BITMAPINFOHEADER structure.

A pretty comprehensive example is available here: Saving a Control Image to a Bitmap File. Of course, it's written for the Compact Framework, but most of the individual components are still applicable. You'll need to P/Invoke several functions from the Windows API (visit www.pinvoke.net for the definitions), and work with a DC.

Taking the drawing into your own hands will probably also be faster, because you're using the GDI subsystem, rather than GDI+. An article on that general approach is available here: 1bpp in C#, and it appears to demonstrate taking matters into your own hands with the BITMAPINFOHEADER struct as well.

If you understand unmanaged C++ code, there's a tutorial available here that might give you some idea of what you'd have to implement in C# to do the same thing: Loading and Saving Bitmaps. As you can see, the code required really isn't that long, albeit still more than the one line Bitmap.Save method.

0
mohammad mohammadi bidmeshki On

I encountered with this problem too and it solved with a simple trick. save the bitmap, then open it as a file stream and change the biSizeimage field manually.

picbpp.Save("pic.bmp", ImageFormat.Bmp);
string path = "pic.bmp";
FileStream fs = File.Open(path, FileMode.Open, FileAccess.Write, FileShare.None);
// Change biSizeimage field manually.
Byte[] info = new byte[] {0x10,0x59};
fs.Seek(34, SeekOrigin.Begin);
fs.Write(info, 0, info.Length);
fs.Close();