您的位置:首页 > 其它

如何生成一个bmp文件

2011-09-01 01:22 561 查看
通过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<<color bits,即,黑白的有1<<1 = 2项,4色有1<<2 = 4项,16色有1<<4 = 16项,256色有1<<8 = 256项) >= 16-bit时没有调色板

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
.rgbBlue = n;

Quad
.rgbGreen = n;

Quad
.rgbRed = n;

Quad
.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;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: