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)
"那些字节是什么,我怎么读它们,这就是问题所在."
这些字节是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图像而不用其他库