bmp格式详解(用于C++编程)

来源:互联网 发布:creo4数据交换配文件 编辑:程序博客网 时间:2024/05/28 14:57

位深度

根据位深度不同,bmp数据的存储格式不同

1:单色图,调色板中含有两种颜色,也就是我们通常说的黑白图片
4:16色图
8:256色图,通常说的灰度图
16:64K图,一般没有调色板,图像数据中每两个字节表示一个像素,5个(555)或6(565)个位表示一个RGB分量
 24:16M真彩色图,一般没有调色板,图像数据中每3个字节表示一个像素,每个字节表示一个RGB分量

32:4G真彩色,一般没有调色板,每4个字节表示一个像素,相对24位真彩图而言,加入了一个透明度,即RGBA模式


也就是说,bmp不能存储16位的灰度图(最大灰度值=65535),16位bmp都是彩色图!只能将16位灰度图线性转换为8位图才能保存为bmp格式,而且要注意保存的不是灰度值,而是其在调色板中的索引值!只有这样,bmp才能正确地被解码!


8位bmp的颜色表

即数据结构tagRGBQUAD的内容,又叫做调色板。为了要把数据流转换为bmp格式,所以要自己填充对应的数据结构,于是就把这部分的内容读取出来,发现是以下内容:

rgbBlue[0] = 0; rgbGreen[0] = 0; rgbRed[0] = 0; rgbReserved[0] = 0;

rgbBlue[1] = 1; rgbGreen[1] = 1; rgbRed[1] = 1; rgbReserved[1] = 0;

...

rgbBlue[255] = 255; rgbGreen[255] = 255; rgbRed[255] = 255; rgbReserved[0] = 0;

因为是灰度图,所以rgb分量相等


位图数据的存储方式

(自下而上,从左到右)
       扫描行是由底向上存储的,这就是说,位图数据的第一个字节表示位图左下角的象素,而最后一个字节表示位图右上角的象素。

每行数据按4字节对齐,如果图像宽度不是4的整数倍,要事先补齐,如下代码:

//计算4字节对齐的高和宽int w1 = (w+3)/4*4;int h1 = (h+3)/4*4;...//填充bmp数据段,pDatamemset(pData,0,bmpFileH.bfSize-bmpFileH.bfOffBits);  //补齐//逐行填充int bits = depth/8;for(int i=0;i<h;i++)//遍历行{const unsigned char * p0 = pRaw + i*w*bits; //pRaw为原始图像数据,其高和宽为h和wunsigned char * p1 = pData + i*w1*bits;for(int j=0;j<w;j++)//遍历列{for(int k=0;k<bits;k++)//遍历通道{*p1++= p0[j*bits+k];}}}...
记得 tagBmpFile中的bfSize要按照4字节对齐后的高和宽计算,而tagBmpInfo中的biWidth、biHeight则按照原始的高和宽赋值


参考资料

BMP位图与调色板分析

2、4、8、16、24、32位位图的数据解析与显示



0 0
原创粉丝点击