多多学习,多多交流
分类: WINDOWS
2015-04-29 20:30:31
原文地址:bitmap文件格式 作者:jiaopeng
BMP(Bitmap_File)图形文件是Windows采用的图形文件格式,在Windows环境下运行的所有图像处理软件都支持BMP图像文件格式。Windows系统内部图像绘制操作都是以BMP为基础的。Windows 3.0以前的BMP文件格式与显示设备有关,因此把这种BMP图像文件格式成为设备相关位图DDB(device-dependent bitmap)文件格式。Windows 3.0以后的BMP图像文件与显示设备无关,因此把这种BMP图像文件格式称为设备无关位图DIB(device-independent bitmap)格式,目的是为了让Windows能够在任何类型的显示设备上显示所存储的图像。BMP位图文件默认的文件扩展名为BMP或者bmp(有时它也会以.DIB或者.RLE作为扩展名)。
文件结构:
位图文件可看成有4个部分组成:位图文件头(bitmap-file header),位图信息头(bitmap-information header),彩色表(color table)和定义位图的字节阵列。
1. 位图文件头:
包含信息:文件类型,文件大小,存放位置等信息。C 中定义为如下结构体:
typedef struct tagBITMAPFILEHEADER {
UINT bfType; //说明文件的类型必须是‘BM’。
DWORD bfSize; //说明文件的大小,用字节为单位
UINT bfReserved1; //保留,但必须为0
UINT bfReserved2; //保留,但必须为0
DWORD bfOffBits; //说明从文件头开始到实际的图像数据之间的字节的偏移量。这个参数是非常有用的,因为位图信息头和调色板的长度会根据不同情况而变化,所以你可以用这个偏移值迅速的从文件中读取到数据位。
}BITMAPFILEHEADER;
2. 位图信息头:
位图信息头(BITMAPINFO)包含位图信息头(BITMAPINFOHEADER)和彩色表(RGBQUAD)
Typedef struct tagBITMAPINFO{
BITMAPINFOHEADER bmiHeader; //包含了有关位图的尺寸及位图格式等信息
RGBQUAD bmiColors[1];//包含索引图像的真实RGB值。
} BITMAPINFO;
Typedef struct tagBITMAPINFOHEADER {
DWORD biSize; //说明BITMAPINFOHEADER结构所需要的字数。
LONG biWidth; //说明图像的宽度,以像素为单位
LONG biHeight; //说明像素的高度,以像素为单位
WORD biPlanes; //为目标设备说明位面数,其值将总是被设为1
WORD biBitCount; //说明比特数/像素,其值为1,4,8,16,24,32
DWORD biCompression; //说明压缩方式
DWORD biSizeImage; //说明图像大小,以字节为单位
LONG biXPelsPerMeter; //说明水平分辨率,用象素/米
LONG biYPelsPerMeter; //说明垂直分辨率,用象素/米
DWORD biClrUsed; //说明位图实际使用的彩色表中的颜色索引数
DWORD biClrImportant; //说明对图像显示有重要影响的颜色索引的数目,如果是0,表示都重要。
} BITMAPINFOHEADER;
现就BITMAPINFOHEADER结构作如下说明:
(1) 彩色表的定位
应用程序可使用存储在biSize成员中的信息来查找在BITMAPINFO结构中的彩色表,如下所示:
pColor = ((LPSTR) pBitmapInfo (WORD) (pBitmapInfo->bmiHeader.biSize))
(2) biBitCount
biBitCount=1 表示位图最多有两种颜色,缺省情况下是黑色和白色,你也可以自己定义这两种颜色。图像信息头装调色板中将有两个调色板项,称为索引0和索引1。图象数据阵列中的每一位表示一个象素。如果一个位是0,显示时就使用索引0的RGB值,如果位是1,则使用索引1的RGB值。
biBitCount=4 表示位图最多有16种颜色。每个象素用4位表示,并用这4位作为彩色表的表项来查找该象素的颜色。 例如,如果位图中的第一个字节为0x
biBitCount=8 表示位图最多有256种颜色。每个象素用8位表示,并用这8位作为彩色表的表项来查找该象素的颜色。例如,如果位图中的第一个字节为0x
biBitCount=16 表示位图最多有216种颜色。每个色素用16位(2个字节)表示。这种格式叫作高彩色,或叫增强型16位色,或64K色。它的情况比较复杂,当biCompression成员的值是BI_RGB时,它没有调色板。16位中,最低的5位表示蓝色分量,中间的5位表示绿色分量,高的5位表示红色分量,一共占用了15位,最高的一位保留,设为0。这种格式也被称作555 16位位图。如果biCompression成员的值是BI_BITFIELDS,那么情况就复杂了,首先是原来调色板的位置被三个DWORD变量占据,称为红、绿、蓝掩码。分别用于描述红、绿、蓝分量在16位中所占的位置。在 95(或98)中,系统可接受两种格式的位域:555和565,在555格式下,红、绿、蓝的掩码分别是:0x
biBitCount=24 表示位图最多有224种颜色。这种位图没有调色板(bmiColors成员尺寸为0),在位数组中,每3个字节代表一个象素,分别对应于颜色R、G、B。
biBitCount=32 表示位图最多有232种颜色。这种位图的结构与16位位图结构非常类似,当biCompression成员的值是BI_RGB时,它也没有调色板,32位中有24位用于存放RGB值,顺序是:最高位—保留,红8位、绿8位、蓝8位。这种格式也被成为888 32位图。如果 biCompression成员的值是BI_BITFIELDS时,原来调色板的位置将被三个DWORD变量占据,成为红、绿、蓝掩码,分别用于描述红、绿、蓝分量在32位中所占的位置。在 95(or 98)中,系统只接受888格式,也就是说三个掩码的值将只能是:0xFF0000、0xFF00、0xFF。而在NT系统中,你只要注意使掩码之间不产生重叠就行。(注:这种图像格式比较规整,因为它是DWORD对齐的,所以在内存中进行图像处理时可进行汇编级的代码优化(简单))。
(3) ClrUsed
BITMAPINFOHEADER结构中的成员ClrUsed指定实际使用的颜色数目。如果ClrUsed设置成0,位图使用的颜色数目就等于biBitCount成员中的数目。请注意,如果ClrUsed的值不是可用颜色的最大值或不是0,则在编程时应该注意调色板尺寸的计算,比如在4位位图中,调色板的缺省尺寸应该是16*sizeof(RGBQUAD),但是,如果ClrUsed的值不是16或者不是0,那么调色板的尺寸就应该是ClrUsed*sizeof(RGBQUAD)。
(4) 图象数据压缩
① BI_RLE8:每个象素为8比特的RLE压缩编码,可使用编码方式和绝对方式中的任何一种进行压缩,这两种方式可在同一幅图中的任何地方使用。
编码方式:由2个字节组成,第一个字节指定使用相同颜色的象素数目,第二个字节指定使用的颜色索引。此外,这个字节对中的第一个字节可设置为0,联合使用第二个字节的值表示:
|
第二个字节的值为0:行的结束。 |
|
第二个字节的值为1:图象结束。 |
|
第二个字节的值为2:其后的两个字节表示下一个象素从当前开始的水平和垂直位置的偏移量。 |
绝对方式:第一个字节设置为0,而第二个字节设置为0x03~0xFF之间的一个值。在这种方式中,第二个字节表示跟在这个字节后面的字节数,每个字节包含单个象素的颜色索引。压缩数据格式需要字边界(word boundary)对齐。下面的例子是用16进制表示的8-位压缩图象数据:
03 04 05 06 00 03 45 56 67 00 02 78 00 02 05 01 02 78 00 00 09 1E 00 01
这些压缩数据可解释为:
压缩数据 |
扩展数据 |
03 04 |
04 04 04 |
05 06 |
06 06 06 06 06 |
00 03 45 56 67 00 |
45 56 67 |
02 78 |
78 78 |
00 02 05 01 |
从当前位置右移5个位置后向下移一行 |
02 78 |
78 78 |
00 00 |
行结束 |
09 1E |
1E 1E 1E 1E 1E 1E 1E 1E 1E |
00 01 |
RLE编码图象结束 |
② BI_RLE4:每个象素为4比特的RLE压缩编码,同样也可使用编码方式和绝对方式中的任何一种进行压缩,这两种方式也可在同一幅图中的任何地方使用。这两种方式是:
编码方式:由2个字节组成,第一个字节指定象素数目,第二个字节包含两种颜色索引,一个在高4位,另一个在低4位。第一个象素使用高4位的颜色索引,第二个使用低4位的颜色索引,第3个使用高4位的颜色索引,依此类推。
绝对方式:这个字节对中的第一个字节设置为0,第二个字节包含有颜色索引数,其后续字节包含有颜色索引,颜色索引存放在该字节的高、低4位中,一个颜色索引对应一个象素。此外,BI_RLE4也同样联合使用第二个字节中的值表示:
|
第二个字节的值为0:行的结束。 |
|
第二个字节的值为1:图象结束。 |
|
第二个字节的值为2:其后的两个字节表示下一个象素从当前开始的水平和垂直位置的偏移量。 |
下面的例子是用16进制数表示的4-位压缩图象数据:
03 04 05 06 00 06 45 56 67 00 04 78 00 02 05 01 04 78 00 00 09 1E 00 01
这些压缩数据可解释为 :
压缩数据 |
扩展数据 |
03 04 |
0 4 0 |
05 06 |
0 6 0 6 0 |
00 06 45 56 67 00 |
4 5 5 6 6 7 |
04 78 |
7 8 7 8 |
00 02 05 01 |
从当前位置右移5个位置后向下移一行 |
04 78 |
7 8 7 8 |
00 00 |
行结束 |
09 1E |
1 E 1 E 1 E 1 E 1 |
00 01 |
RLE图象结束 |
彩色表:彩色表包含的元素与位图所具有的颜色数相同。
typedef struct tagRGBQUAD { /* rgbq */
BYTE rgbBlue;
BYTE rgbGreen;
BYTE rgbRed;
BYTE rgbReserved;
} RGBQUAD;
位图数据
长度由图像尺寸,象素位数,压缩方式等共同决定.
由于存储要求,图像的列数必须为4的整数倍