bmpbmp 头文件格式头文件格式1:BMP 文件组成 BMP 文件由文件头、位图信息头、颜色信息和图形数据四部分组成2:BMP 文件头(14字节)BMP 文件头数据结构含有 BMP 文件的类型、文件大小和位图起始位置等信息其结构定义如下:typedef struct tagBITMAPFILEHEADER{WORDbf Type; // 位图文件的类型,必须为 BMP(0-1字节)DWORD bfSize; // 位图文件的大小,以字节为单位(2-5字节)WORD bfReserved1; // 位图文件保留字,必须为0(6-7字节)WORD bfReserved2; // 位图文件保留字,必须为0(8-9字节)DWORD bfOffBits; // 位图数据的起始位置,以相对于位图(10-13字节)// 文件头的偏移量表示,以字节为单位} BITMAPFILEHEADER;3:位图信息头(40字节)BMP 位图信息头数据用于说明位图的尺寸等信息typedef struct tagBITMAPINFOHEADER{DWORD biSize; // 本结构所占用字节数(14-17字节)LONG biWidth; // 位图的宽度,以像素为单位(18-21字节)LONG biHeight; // 位图的高度,以像素为单位(22-25字节)WORD biPlanes; // 目标设备的级别,必须为1(26-27字节)WORD biBitCount;// 每个像素所需的位数,必须是1(双色),(28-29字节)// 4(16色),8(256色)或24(真彩色)之一DWORD biCompression; // 位图压缩类型,必须是 0(不压缩),(30-33字节)// 1(BI_RLE8压缩类型)或2(BI_RLE4压缩类型)之一DWORD biSizeImage; // 位图的大小,以字节为单位(34-37字节)LONG biXPelsPerMeter; // 位图水平分辨率,每米像素数(38-41字节)LONG biYPelsPerMeter; // 位图垂直分辨率,每米像素数(42-45字节)DWORD biClrUsed;// 位图实际使用的颜色表中的颜色数(46-49字节)DWORD biClrImportant;// 位图显示过程中重要的颜色数(50-53字节)} BITMAPINFOHEADER;4:颜色表 颜色表用于说明位图中的颜色,它有若干个表项,每一个表项是一个 RGBQUAD 类型的结构,定义一种颜色。
RGBQUAD 结构的定义如下:typedef struct tagRGBQUAD {BYTE rgbBlue;// 蓝色的亮度(值范围为0-255)BYTE rgbGreen; // 绿色的亮度(值范围为0-255)BYTE rgbRed; // 红色的亮度(值范围为0-255)BYTE rgbReserved;// 保留,必须为0} RGBQUAD;颜色表中 RGBQUAD 结构数据的个数有 biBitCount 来确定:当 biBitCount=1,4,8时,分别有2,16,256个表项;当 biBitCount=24时,没有颜色表项位图信息头和颜色表组成位图信息,BITMAPINFO 结构定义如下:typedef struct tagBITMAPINFO {BITMAPINFOHEADER bmiHeader; // 位图信息头RGBQUAD bmiColors[1]; // 颜色表} BITMAPINFO;5:位图数据位图数据记录了位图的每一个像素值,记录顺序是在扫描行内是从左到右,扫描行之间是从下到上位图的一个像素值所占的字节数: 当 biBitCount=1时,8个像素占1个字节;当 biBitCount=4时,2个像素占1个字节;当 biBitCount=8时,1个像素占1个字节;当 biBitCount=24时,1个像素占3个字节;Windows 规定一个扫描行所占的字节数必须是4的倍数(即以 long 为单位),不足的以0填充,biSizeImage = ((((bi.biWidth * bi.biBitCount) + 31) 具体数据举例:具体数据举例:如某 BMP 文件开头:4D42 4690 0000 0000 0000 4600 0000 2800 0000 8000 0000 9000 0000 0100*1000 0300 0000 0090 0000 A00F 0000 A00F 0000 0000 0000 0000 0000*00F8 0000 E007 0000 1F00 0000 0000 0000*02F1 84F1 04F1 84F1 84F1 06F2 84F1 06F2 04F2 86F2 06F2 86F2 86F2 .... .... BMP 文件可分为四个部分:位图文件头、位图信息头、彩色板、图像数据阵列,在上图中已用*分隔。
一 图像文件头1)1:(这里的数字代表的是“字“,即两个字节,下同)图像文件头0x4D42=’BM’ ,表示是 Windows 支持的 BMP 格式2)2-3:整个文件大小4690 0000,为 00009046h=369343)4-5:保留,必须设置为 04)6-7:从文件开始到位图数据之间的偏移量4600 0000,为00000046h=70,上面的文件头就是 35 字=70 字节二 位图信息头5)8-9:位图图信息头长度6)10-11:位图宽度,以像素为单位8000 0000,为00000080h=1287)12-13:位图高度,以像素为单位9000 0000,为00000090h=144 8)14:位图的位面数,该值总是 10100,为0001h=19)15:每个像素的位数有 1(单色) ,4(16 色) ,8(256色) ,16(64K 色,高彩色) ,24(16M 色,真彩色) ,32(4096M 色,增强型真彩色) 1000 为 0010h=1610)16-17:压缩说明:有 0(不压缩) ,1(RLE 8,8 位 RLE 压缩) ,2(RLE 4,4 位 RLE 压缩,3(Bitfields,位域存放) 。
RLE 简单地说是采用像素数+像素值的方式进行压缩T408 采用的是位域存放方式,用两个字节表示一个像素,位域分配为 r5b6g5图中0300 0000 为 00000003h=311)18-19:用字节数表示的位图数据的大小,该数必须是 4 的倍数,数值上等于(≥位图宽度的最小的 4 的倍数)×位图高度×每个像素位数0090 0000 为 00009000h=80×90×2h=3686412)20-21:用象素/米表示的水平分辨率A00F 0000 为 0000 0FA0h=400013)22-23:用象素/米表示的垂直分辨率A00F 0000 为 0000 0FA0h=400014)24-25:位图使用的颜色索引数设为 0 的话,则说明使用所有调色板项15)26-27:对图象显示有重要影响的颜色索引的数目如果是0,表示都重要三、彩色板16)28-....(不确定):彩色板规范对于调色板中的每个表项,用下述方法来描述 RGB 的值:1 字节用于蓝色分量1 字节用于绿色分量1 字节用于红色分量1 字节用于填充符(设置为 0)对于 24-位真彩色图像就不使用彩色板,因为位图中的 RGB 值就代表了每个象素的颜色。
如,彩色板为 00F8 0000 E007 0000 1F00 0000 0000 0000,其中:00FB 0000 为 FB00h=1111100000000000(二进制) ,是蓝色分量的掩码E007 0000 为 07E0h=0000011111100000(二进制) ,是绿色分量的掩码1F00 0000 为 001Fh=0000000000011111(二进制) ,是红色分量的掩码0000 0000 总设置为 0将掩码跟像素值进行“与”运算再进行移位操作就可以得到各色分量值看看掩码,就可以明白事实上在每个像素值的两个字节16 位中,按从高到低取 5、6、5 位分别就是 r、g、b 分量值取出分量值后把 r、g、b 值分别乘以 8、4、8 就可以补齐第个分量为一个字节,再把这三个字节按 rgb 组合,放入存储器(同样要反序) ,就可以转换为 24 位标准 BMP 格式了四、图像数据阵列 17)27(无调色板)-. . .:每两个字节表示一个像素阵列中的第一个字节表示位图左下角的象素,而最后一个字节表示位图右上角的象素五、存储算法BMP 文件通常是不压缩的,所以它们通常比同一幅图像的压缩图像文件格式要大很多。
例如,一个 800×600 的 24 位几乎占据1.4MB 空间因此它们通常不适合在因特网或者其它低速或者有容量限制的媒介上进行传输 根据颜色深度的不同,图像上的一个像素可以用一个或者多个字节表示,它由 n/8 所确定(n 是位深度,1字节包含 8 个数据位) 图片浏览器等基于字节的 ASCII 值计算像素的颜色,然后从调色板中读出相应的值更为详细的信息请参阅下面关于位图文件的部分 n 位 2n 种颜色的位图近似字节数可以用下面的公式计算: BMP 文件大小约等于 54+4*2 的 n 次方+(w*h*n)/8,其中高度和宽度都是像素数 需要注意的是上面公式中的 54是位图文件的文件头,是彩色调色板的大小另外需要注意的是这是一个近似值,对于 n 位的位图图像来说,尽管可能有最多 2n 中颜色,一个特定的图像可能并不会使用这些所有的颜色由于彩色调色板仅仅定义了图像所用的颜色,所以实际的彩色调色板将小于 如果想知道这些值是如何得到的,请参考下面文件格式的部分 由于存储算法本身决定的因素,根据几个图像参数的不同计算出的大小与实际的文件大小将会有一些细小的差别。