BMP全名Bitmap(位图),是一种图片格式。格式即一种约定或规定,BMP图片,即数据按照BMP格式的规定来存储、读取和传送数据。
举个例子,测试图(点击就能到链接地址了,图片来之国外的一个测试图片库)
MD5:B4CA8C9BF43BDBED60132560027AB020
SHA-1:5FDB1AB7DB087B5238D85C5C1A9E333BE2DDE211
ex:分析测试图中的数据
从上图左上角可以看到,该测试图由:1、文件表头,2、信息表头,3、图像数据,三部分构成。
1、文件表头 BITMAPFILEHEADER---C++ code
- typedef struct tagBITMAPFILEHEADER {/* bmfh */
- WORD bfType; //文件类型,0x4D42,查ASCII表即字符'BM'
- DWORD bfSize; //文件大小,0xb6631200--因为字节顺序0x001263b6,十进制即为1205174
- WORD bfReserved1; //保留,默认为0
- WORD bfReserved2; //保留,默认为0
- DWORD bfOffBits; /**说明从文件头开始到实际的图象数据之间的字节的偏移量。
- *该参数非常有用,因为位图信息头和调色板的长度会根据不同情况而变化,所以可以用
- *这个偏移值迅速的从文件中读取到位数据。0x0036说明图像数据就是上图黄底色后面的部分**/
- } BITMAPFILEHEADER, *PBITMAPFILEHEADER;
typedef struct tagBITMAPFILEHEADER {/* bmfh */ WORD bfType; //文件类型,0x4D42,查ASCII表即字符'BM' DWORD bfSize; //文件大小,0xb6631200--因为字节顺序0x001263b6,十进制即为1205174 WORD bfReserved1; //保留,默认为0 WORD bfReserved2; //保留,默认为0 DWORD bfOffBits; /**说明从文件头开始到实际的图象数据之间的字节的偏移量。 *该参数非常有用,因为位图信息头和调色板的长度会根据不同情况而变化,所以可以用 *这个偏移值迅速的从文件中读取到位数据。0x0036说明图像数据就是上图黄底色后面的部分**/ } BITMAPFILEHEADER, *PBITMAPFILEHEADER;
2、信息表头 BITMAPINFOHEADER---C++ code
- typedef struct tagBITMAPINFOHEADER { /* bmih */
- DWORD biSize; //BITMAPINFOHEADER结构所需要的字节数 0x00000028,即0x28个字节
- LONG biWidth; //图象宽度,以象素为单位0x000002ea,即746个像素
- LONG biHeight; /**图象高度,以象素为单位。注:这个值除了用于描述图像的高度之外
- *它还有另一个用处,就是指明该图像是倒向的位图,还是正向的位图。如果该值是一个正数,说明
- *图像是倒向的,如果该值是一个负数,则说明图像是正向的。大多数的BMP文件都是倒向的位图,也
- *就是时,高度值是一个正数。0x0000021a,即538个像素**/
- WORD biPlanes; //说明目标设备的位面数
- WORD biBitCount; //比特数/象素,0x0018,即24
- DWORD biCompression; //图象数据压缩的类型,0x00000000,表示没有压缩
- DWORD biSizeImage; //图象数据大小,0x00126380,即1205120
- LONG biXPelsPerMeter; //水平分辨率,用象素/米,0x00000000
- LONG biYPelsPerMeter; //垂直分辨率,用象素/米,0x00000000
- DWORD biClrUsed; //位图实际使用的彩色表中的颜色索引数(设为0的话,则说明使用所有调色板项)。
- DWORD biClrImportant; //对图象显示有重要影响的颜色索引的数目,如果是0,表示都重要。
- } BITMAPINFOHEADER;
typedef struct tagBITMAPINFOHEADER { /* bmih */
DWORD biSize; //BITMAPINFOHEADER结构所需要的字节数 0x00000028,即0x28个字节
LONG biWidth; //图象宽度,以象素为单位0x000002ea,即746个像素
LONG biHeight; /**图象高度,以象素为单位。注:这个值除了用于描述图像的高度之外
*它还有另一个用处,就是指明该图像是倒向的位图,还是正向的位图。如果该值是一个正数,说明
*图像是倒向的,如果该值是一个负数,则说明图像是正向的。大多数的BMP文件都是倒向的位图,也
*就是时,高度值是一个正数。0x0000021a,即538个像素**/
WORD biPlanes; //说明目标设备的位面数
WORD biBitCount; //比特数/象素,0x0018,即24
DWORD biCompression; //图象数据压缩的类型,0x00000000,表示没有压缩
DWORD biSizeImage; //图象数据大小,0x00126380,即1205120
LONG biXPelsPerMeter; //水平分辨率,用象素/米,0x00000000
LONG biYPelsPerMeter; //垂直分辨率,用象素/米,0x00000000
DWORD biClrUsed; //位图实际使用的彩色表中的颜色索引数(设为0的话,则说明使用所有调色板项)。
DWORD biClrImportant; //对图象显示有重要影响的颜色索引的数目,如果是0,表示都重要。
} BITMAPINFOHEADER;
块名称 | 对应Windows结构体定义 | 大小(Byte) |
文件信息头 | BITMAPFILEHEADER | 14 |
位图信息头 | BITMAPINFOHEADER | 40 |
RGB颜色阵列 | BYTE* | 由图像长宽尺寸决定 |
3、图像数据
由2中绿色的显示为24位的RGB位像素数据,其实际读取格式:
蓝色B值 | 绿色G值 | 红色R值 |
===========================华丽的分割=============================
4、补充:
完整的BMP结构:1、文件信息头,2、位图信息头,3、彩色表,4、位图数据阵列
位图信息头中biBitCount有不同的取值:
biBitCount=1 表示位图最多有两种颜色,缺省情况下是黑色和白色;
biBitCount=4 表示位图最多有16种颜色。每个象素用4位表示,并用这4位作为彩色表的表项来查找该象素的颜色。
biBitCount=8 表示位图最多有256种颜色。每个象素用8位表示,并用这8位作为彩色表的表项来查找该象素的颜色。
biBitCount=16表示位图最多有65536种颜色。每个色素用16位(2个字节)表示。这种格式叫作高彩色,或叫增强型16位色,或64K色。
它的情况比较复杂,当biCompression成员的值是BI_RGB时,它没有调色板。16位中,最低的5位表示蓝色分量,中间的5位表示绿色分量,高的5位表示红色分量,一共占用了15位,最高的一位保留,设为0。这种格式也被称作555 16位位图。如果biCompression成员的值是BI_BITFIELDS,那么情况就复杂了,首先是原来调色板的位置被三个DWORD变量占据,称为红、绿、蓝掩码。分别用于描述红、绿、蓝分量在16位中所占的位置。在Windows 95(或98)中,系统可接受两种格式的位域:555和565,在555格式下,红、绿、蓝的掩码分别是:0x7C00、0x03E0、0x001F,而在565格式下,它们则分别为:0xF800、0x07E0、0x001F。你在读取一个像素之后,可以分别用掩码“与”上像素值,从而提取出想要的颜色分量(当然还要再经过适当的左右移操作)。在NT系统中,则没有格式限制,只不过要求掩码之间不能有重叠。(注:这种格式的图像使用起来是比较麻烦的,不过因为它的显示效果接近于真彩,而图像数据又比真彩图像小的多,所以,它更多的被用于游戏软件)。
biBitCount=24 表示位图最多有1670万种颜色。这种位图没有调色板(bmiColors成员尺寸为0),在位数组中,每3个字节代表一个象素,分别对应于颜色R、G、B。
biBitCount=32 表示位图最多有4294967296(2的32次方)种颜色。这种位图的结构与16位位图结构非常类似,当biCompression成员的值是BI_RGB时,它也没有调色板,32位中有24位用于存放RGB值,顺序是:最高位—保留,红8位、绿8位、蓝8位。这种格式也被成为888 32位图。如果 biCompression成员的值是BI_BITFIELDS时,原来调色板的位置将被三个DWORD变量占据,成为红、绿、蓝掩码,分别用于描述红、绿、蓝分量在32位中所占的位置。在Windows 95(or 98)中,系统只接受888格式,也就是说三个掩码的值将只能是:0xFF0000、0xFF00、0xFF。而在NT系统中,你只要注意使掩码之间不产生重叠就行。(注:这种图像格式比较规整,因为它是DWORD对齐的,所以在内存中进行图像处理时可进行汇编级的代码优化(简单))。
行对齐:Windows规定一个扫描行所占的字节数必须是4的倍数,不足的以0填充。
一个扫描行所占的字节数计算方法:
DataSizePerLine= (biWidth* biBitCount+31)/8
以上内容仅供参考,更详细的内容请google搜索及参见参考文献!