通过windows API函数利用已知的二进制数据生成一个bmp文件
BMP file = BMP file header + BMP info header[ + palatte data] + color data
1。调色板数据:对于增强16位或更高彩色的图象,没有调色板数据。
具体内容看msdn,可能是叫RGBQUAD吧
2。颜色数据:单行的数据量大小是length*height*bit per pixel/8
每行对齐到4字节边界,不足的补0x0.
行的存储方式是从左到右,最底下的行最先存储,既存储的上下顺序是倒的,左右顺序不变。
3。根据已知的数据大小,确定位图的长、高和颜色数,填写BMPFILEHEADER和BMPINFOHEADER,如果数据不包含调色板,要先用WIN API创建一个同等数目的调色板(item count = 1<
4。依次把BMPFILEHEADER,BMPINFOHEADER,palatte,和颜色数据写入文件就好了,假如没有调色板数据,写完BMPINFOHEADER就写数据.
颜色数据每行对齐到4字节边界,就是说每行的数据的字节数必须是4的倍数。但是他没有给出确切的公式,每行数据的
字节数的计算公式是:(Width*BitPerPixel+31)/32*4。假如你已经有了灰阶
的图像数据(8位),存放次序为从左到右,从上到下,每行数据之间没有添
加额外的数据,那么可以这样生成一个BITMAP文件。
bool SaveGrayDataToBmp(BYTE* Data, int W, int H,
const char* BmpFile)
{
FILE *fp;
bool ret;
UINT nPad;
BYTE Pad[4];
RGBQUAD Quad[256];
BITMAPFILEHEADER bfh;
BITMAPINFOHEADER bih;
//设定BITMAPFILEHEADER
memset(&bfh, 0, sizeof(bfh));
bfh.bfType = 'BM';
bfh.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(
BITMAPINFOHEADER) + sizeof(RGBQUAD)*256 +
((W*8+31)/32*4)*H;
bfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(
BITMAPINFOHEADER) + sizeof(RGBQUAD)*256;
//设定BITMAPINFOHEADER
memset(&bih, 0, sizeof(bih));
bih.biSize = sizeof(bih);
bih.biWidth = W;
bih.biHeight = H;
bih.biPlanes = 1; //必须为1
bih.biBitCount = 8;
//设定调色盘数据Quad
for(int n=0; n<256; n++) {
Quad[n].rgbBlue = n;
Quad[n].rgbGreen = n;
Quad[n].rgbRed = n;
Quad[n].rgbReserved = 0;
}
//下面写数据到BITMAP文件
fp = fopen(BmpFile, "wb");
if (fp==NULL) return false;
fwrite(&bfh, 1, sizeof(bfh), fp);
fwrite(&bih, 1, sizeof(bih), fp);
fwrite(Quad, 1, sizeof(Quad), fp);
//下面写入数据部分,注意,bmp的数据上下是颠倒的
Data = Data + W*(H-1); //因为上下颠倒,所以需要将Data指向最后
//一行,以后再对Data进行减操作。
nPad = ((W*8+31)/32*4) - W; //因为bmp每行的数据为4的倍数,所以
//需要在每行后面补0,nPad为补的字节数
memset(Pad, 0, sizeof(Pad));
for(int h=H-1; h>=0; h--) {
fwrite(Data, 1, W, fp);
fwrite(Pad, 1, nPad, fp);
Data = Data - W; 因为上下颠倒,Data是倒退着写入文件
}
ret = ferror()==0; fclose(fp);
return ret;
}