【发布时间】:2012-06-03 06:59:20
【问题描述】:
我无法理解 BMP 格式,我知道它应该很简单,但不知何故我遗漏了一些东西。我以为是 2 个标头,后跟定义图像的实际字节,但数字不加起来。
例如,我只是尝试将此 BMP 文件加载到内存中(640x480 8bpp 灰度),然后将其写回另一个文件。据我了解,有两个不同的标题 BITMAPFILEHEADER 和 BITMAPINFOHEADER。 BITMAPFILEHEADER 是 14 字节,而 BITMAPINFOHEADER 是 40 字节(这取决于 BMP,我怎么能说这是另一个故事)。无论如何,BITMAPFILEHEADER 通过其参数 bfOffBits 表示位图位从偏移量 1078 开始。这意味着还有 1024 ( 1078 - (40+14) ) 个其他字节,携带更多信息。这些字节是什么,我如何读取它们,这就是问题所在。还是有更正确的方法来加载 BMP 并将其写入磁盘?
这里是我使用的代码供参考(顺便说一句,我在 windows 下做所有这些。)
#include <windows.h>
#include <iostream>
#include <stdio.h>
HANDLE hfile;
DWORD written;
BITMAPFILEHEADER bfh;
BITMAPINFOHEADER bih;
int main()
hfile = CreateFile("image.bmp",GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
ReadFile(hfile,&bfh,sizeof(bfh),&written,NULL);
ReadFile(hfile,&bih,sizeof(bih),&written,NULL);
int imagesize = bih.biWidth * bih.biHeight;
image = (unsigned char*) malloc(imagesize);
ReadFile(hfile,image,imagesize*sizeof(char),&written,NULL);
CloseHandle(hfile);
然后我正在做与写入文件完全相反的操作,
hfile = CreateFile("imageout.bmp",GENERIC_WRITE,FILE_SHARE_WRITE,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
WriteFile(hfile,&bfh,sizeof(bfh),&written,NULL);
WriteFile(hfile,&bih,sizeof(bih),&written,NULL);
WriteFile(hfile,image,imagesize*sizeof(char),&written,NULL);
CloseHandle(hfile);
编辑 --- 已解决
好吧,我终于做对了,毕竟它并不复杂。正如 Viktor 指出的,这 1024 个字节代表调色板。
我在代码中添加了以下内容:
RGBQUAD palette[256];
// [...] previous declarations [...] int main() [...] then read two headers
ReadFile(hfile,palette,sizeof(palette),&written,NULL);
然后当我回信时,我添加了以下内容,
WriteFile(hfile,palette,sizeof(palette),&written,NULL);
【问题讨论】:
-
从图像中读取 biBitCount 时设置为什么?如果如你所说,它是一个 8 位图像,它应该有一个你需要处理的调色板。
-
你为什么用 C++ 标签标记 C 问题?