将位图保存到文件在图像大小字段中为零

时间:2011-01-27 05:01:26

标签: c# .net bitmap gdi+ bitmapdata

当我使用格式为ImageFormat.Bmp的Bitmap.Save方法时,我发现文件中的位图标题信息在biSizeImage字段中为零。

根据规格,我可以看到这是可以的,但不幸的是,我被迫使用的蹩脚的嵌入式设备坚持正确设置。

所以问题是如何在保存位图时始终设置此标题信息字段?

2 个答案:

答案 0 :(得分:3)

正如您所怀疑的那样,问题是0是RGB位图的图像大小字段的完全允许值。 BITMAPINFOHEADER结构的MSDN documentation证实了这一事实:

  

<强> biSizeImage
  图像的大小(以字节为单位)。对于BI_RGB位图,这可以设置为零。

     

如果biCompressionBI_JPEGBI_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();