当我使用格式为ImageFormat.Bmp的Bitmap.Save方法时,我发现文件中的位图标题信息在biSizeImage字段中为零。
根据规格,我可以看到这是可以的,但不幸的是,我被迫使用的蹩脚的嵌入式设备坚持正确设置。
所以问题是如何在保存位图时始终设置此标题信息字段?
答案 0 :(得分:3)
正如您所怀疑的那样,问题是0是RGB位图的图像大小字段的完全允许值。 BITMAPINFOHEADER
结构的MSDN documentation证实了这一事实:
<强> biSizeImage 强>
图像的大小(以字节为单位)。对于BI_RGB
位图,这可以设置为零。如果
biCompression
为BI_JPEG
或BI_PNG
,则biSizeImage
分别表示JPEG或PNG图像缓冲区的大小。
因此,.NET Framework中的实现只是以标准的,文档化的方式执行。由于您还需要其他内容,因此您必须自己处理保存到文件的过程,这样您就可以手动修改biSizeImage
结构的BITMAPINFOHEADER
成员。
这里有一个非常全面的例子:Saving a Control Image to a Bitmap File。当然,它是为Compact Framework编写的,但大多数单个组件仍然适用。您需要从Windows API P / Invoke几个函数(访问www.pinvoke.net获取定义),并使用DC。
将绘图掌握在自己手中可能也会更快,因为您使用的是GDI子系统,而不是GDI +。这里提供了一篇关于这种一般方法的文章:1bpp in C#,它似乎也证明了使用BITMAPINFOHEADER
结构自行解决问题。
如果您了解非托管C ++代码,那么此处提供的教程可能会让您了解在C#中必须实现的内容,以执行相同的操作:Loading and Saving Bitmaps。正如您所看到的,所需的代码确实不是很长,尽管仍然超过一行Bitmap.Save
方法。
答案 1 :(得分:0)
我也遇到了这个问题,并用一个简单的技巧解决了。
保存位图,然后将其作为文件流打开并手动更改biSizeimage
字段。
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();