BMP是Windows中一种标准图像格式,全称是Microsoft设备独立位图(device independent bitmap,DIP),又称位图。一个位图文件只能存放一幅图像。按照像素位数的不同(1位,4位,8位,24位),分别对应为单色,16色,256色,真彩色。即在一个4位图中,能够描述的颜色为2的4次方16种。在BMP文件中,采用小端存储方式,低地址存放低位数据,高地址存放高位数据。
BMP文件的数据按照从文件头开始的先后顺序分为四个部分:
1. bmp文件头(bmp file header):文件的格式、大小等信息。
2. 位图信息头(bitmap information):提供图像数据的尺寸、位平面数、压缩方式、颜色索引等信息。
3. 调色板(color palate):可选,如使用索引来表示图像,调色板就是索引与其对应的颜色的映射表。
4. 位图数据(bitmap data):图像数据。
一个bmp文件可用代码按如下表示:
typedef struct tagBITMAP_FILE{
BITMAPFILEHEADER bitmapheader;
BITMAPINFOHEADER bitmapinfoheader;
PALETTEENTRY palette[256];
UCHAR *buffer;
} BITMAP_FILE
1、 BMP文件头:BITMAPFILEHEADER
1
2
3
4
5
6
7
8
9
|
typedef
struct
tagBITMAPFILEHEADER
{
WORD
bfType;
//位图文件的类型,必须为BM(1-2字节)
DWORD
bfSize;
//位图文件的大小,以字节为单位(3-6字节,低位在前)
WORD
bfReserved1;
//位图文件保留字,必须为0(7-8字节)
WORD
bfReserved2;
//位图文件保留字,必须为0(9-10字节)
DWORD
bfOffBits;
//位图数据的起始位置,以相对于位图(11-14字节,低位在前)
//文件头的偏移量表示,以字节为单位
}BITMAPFILEHEADER;
|
2、位图信息段:BITMAPINFOHEADER
123456789101112131415typedef
struct
tagBITMAPINFOHEADER{
DWORD
biSize;
//本结构所占用字节数(15-18字节)
LONG
biWidth;
//位图的宽度,以像素为单位(19-22字节)
LONG
biHeight;
//位图的高度,以像素为单位(23-26字节)
WORD
biPlanes;
//目标设备的级别,必须为1(27-28字节)
WORD
biBitCount;
//每个像素所需的位数,必须是1(黑白图像),(29-30字节)
//4(16色),8(256色)16(高彩色),24(真彩色),新的BMP格式支持32位色。
DWORD
biCompression;
//位图压缩类型,有效的值为BI_RGB(不压缩),(31-34字节)
//BI_RLE8,BI_RLE$,BI_BITFILEDS(均为 windows定义常量)
DWORD
biSizeImage;
//实际位图数据占用的字节数(其中包含了为了补齐行数是4的倍数而添加的空字节),以字节为单位(35-38字节)
LONG
biXPelsPerMeter;
//位图水平分辨率,每米像素数(39-42字节)
LONG
biYPelsPerMeter;
//位图垂直分辨率,每米像素数(43-46字节)
DWORD
biClrUsed;
//位图实际使用的的颜色数(47-50字节)
DWORD
biClrImportant;
//位图显示过程中重要的颜色数(51-54字节)
}BITMAPINFOHEADER;
其中位图的宽度必须为4的倍数。因为windows在进行扫描时候的最小单位是4个字节,不足时,用0进行填充。
一个扫描行所占真实字节数的计算公式如下:
DataSizePerLine=(biWidth * biBitCount /8+ 3)/4* 4
BMP文件头与位图信息段合起来可叫做位图头文件,固定长度为54个字节。
3、颜色表
颜色表用于说明位图中的颜色,它有若干个表项,每一个表项是一个RGBQUAD类型的结构,定义一种颜色。RGBQUAD结构的定义如下:
123456typedef
struct
tagRGBQUAD{
BYTE
rgbBlue;
//该颜色的蓝色分量(值范围为0-255)
BYTE
rgbGreen;
//该颜色的绿色分量(值范围为0-255)
BYTE
rgbRed;
//该颜色的红色分量(值范围为0-255)
BYTE
rgbReserved;
//保留,必须为0
}RGBQUAD;
为什么需要颜色表呢?以一幅100X100的4位图为例。如果不采用颜色表,R、G、B的取值范围都是0~255,各需要一个字节。则该图像需要100X100X3=30000字节。当采用了颜色表,像素位只需要保存颜色表的索引即可。还是以100X100的4位图为例,只需要4位半个字节就能对应颜色表中的所有信息。颜色表的大小为16X3=48位。图像的总字节数位100X100X0.5+48=5048。可见采用颜色表大大减少了图像的大小。对24位真彩色图而言,使用颜色表只能加大图像占用的内存。如果以24位用作索引,还需加上一张大小为256X256X256X3字节的颜色表。还不如直接使用24位保存颜色信息。
4、位图数据
记录了图像的每一个像素值。对于有颜色表的位图,位图数据就是该像素颜色在调色板中的索引值;对于真彩色图,位图数据就是实际的R、G、B值。
BMP文件的数据是从图像的左下角开始逐行扫描的,即从下到上、从左到右,将图像的像素值一一记录下来,因此图像的坐标零点在图像的左下角。