在C中加载8bpp灰度BMP

Reg*_*ser 4 c windows image bmp

我无法理解BMP格式,我知道它应该很简单,但不知怎的,我错过了一些东西.我认为它是2个标题后跟定义图像的实际字节,但数字不加起来.

例如,我只是尝试将此BMP文件加载到内存(640x480 8bpp灰度)中,然后将其写回另一个文件.据我所知,有两种不同的标题BITMAPFILEHEADER和BITMAPINFOHEADER.BITMAPFILEHEADER是14个字节,BITMAPINFOHEADER是40个字节(这个取决于BMP,我怎么能告诉那是另一个故事).无论如何,BITMAPFILEHEADER通过其参数bfOffBits表示位图位从偏移1078开始.这意味着有1024(1078 - (40 + 14))个其他字节,携带更多信息.那些字节是什么,我怎么读它们,这就是问题所在.或者是否有更正确的方法来加载BMP并将其写入磁盘?

这里参考的是我使用的代码(我在windows btw下做了所有这些.)

#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);
Run Code Online (Sandbox Code Playgroud)

我正在做与写入文件完全相反的事情,

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);
Run Code Online (Sandbox Code Playgroud)

编辑---解决了

好的,所以我终于做对了,毕竟它并不是很复杂.正如Viktor所指出的,这1024个字节代表了调色板.

我在代码中添加了以下内容:

RGBQUAD palette[256];
// [...] previous declarations [...] int main() [...] then read two headers
ReadFile(hfile,palette,sizeof(palette),&written,NULL);
Run Code Online (Sandbox Code Playgroud)

然后当我回信时,我添加了以下内容,

WriteFile(hfile,palette,sizeof(palette),&written,NULL);
Run Code Online (Sandbox Code Playgroud)

Vik*_*pov 7

"那些字节是什么,我怎么读它们,这就是问题所在."

这些字节是Palette(或.BMP格式术语中的ColorTable),如评论中提到的Retired Ninja.基本上,它是一个表,它指定了位图数据中遇到的每个8bpp值使用的颜色.

对于灰度,调色板是微不足道的(我不是在谈论颜色模型和RGB - >灰度转换):

for(int i = 0 ; i < 256 ; i++)
{
    Palette[i].R = i;
    Palette[i].G = i;
    Palette[i].B = i;
}
Run Code Online (Sandbox Code Playgroud)

但是,ColorTable的条目中有一些填充,因此需要4*256字节而不是256*3.ColorTable条目中的第四个组件(RGBQUAD Struct)不是"alpha通道",它只是"保留"的东西.请参阅RGBQUAD上的MSDN(MSDN,RGBQUAD).

详细的格式描述可以在维基百科页面上找到:Wiki,bmp格式

还有关于SO的RGBQUAD结构的这个链接问题:用纯c/c ++编写BMP图像而不用其他库