BMP图片格式

BMP文件格式,又称为Bitmap(位图),是Windows系统中广泛使用的图像文件格式。由于它可以不作任何变换地保存图像像素域的数据,因此成为我们取得RAW数据的重要来源。Windows的图形用户界面(graphical user interfaces)也在它的内建图像子系统GDI中对BMP格式提供了支持。

BMP文件的数据格式按照从文件头开始的先后顺序分为四个部分:

Ø bmp 文件头 (bmp file header): (14 字节 ) 提供文件的格式、大小等信息

Ø 位图信息头 (bitmap information): (40 字节 ) 提供图像数据的尺寸、位平面数、压缩方式、颜色索引等信息

Ø 调色板 (color palette): (xx 字节 ) 可选,如使用索引来表示图像,调色板就是索引与其对应的颜色的映射表

Ø 位图数据 (bitmap data): (xx 字节 ) 就是图像数据啦

我们一般见到的图像以24位图像为主,即R、G、B三种颜色各用8个bit来表示,这样的图像我们称为真彩色,这种情况下是不需要调色板的,也就是所位图信息头后面紧跟的就是位图数据了。因此,我们常常见到有这样一种说法:位图文件从文件头开始偏移 54 个字节就是位图数据了,这其实说的是24 或32 位图的情况。这也就解释了我们按照这种程序写出来的程序为什么对某些位图文件没用了。

在BMP文件中,数据采用小端方式(little endian)。即如果一个数据需要用几个字节来表示的话,那么该数据的存放字节顺序为“低地址存放低位数据,高地址存放高位数据”。如BMP的类型0x4D42 在内存中的存储顺序为:42 4d

typedef struct tagBITMAPFILEHEADER {
  UINT bfType;     // 位图文件的类型,必须为字符 BM 即0x4D42 (0-1 字节 )  
  DWORD bfSize;    // 位图文件的大小,以字节为单位           (2-5 字节)  
  UINT bfReserved1;// 位图文件保留字,必须为 0              (6-7 字节 ) 
  UINT bfReserved2;// 位图文件保留字,必须为 0              (8-9 字节 ) 
  DWORD bfOffBits; // 位图数据的起始位置,以相对于位图       (10-13 字节 ) 
 } BITMAPFILEHEADER;

文件大小 0x2A308A = 2764938字节与文件属性一致。位图起始位置从文件头偏移0x8A

0x2a308a = 2 * 16^5 + 10 * 16^4+3 * 16^3 + 0 * 16^2 +8 * 16^1 + 0 * 16^0

typedef struct tagBITMAPINFOHEADER
 {
DWORD biSize;         //本结构所占用字节数,一般是40个字节 (14-17 共4字节 ) 
LONG biWidth;         // 位图的宽度,以像素为单位 (18-21 共4字节 )  
LONG biHeight;        // 位图的高度,以像素为单位 (22-25 共4字节 )
                         这个值还表示位图是正向还是倒向。正数倒向位图,负数正向位图
WORD biPlanes;        // 目标设备的级别,必须为 1 (26-27 共2字节 ) 
WORD biBitCount;      // 每个像素所需的位数,必须是1,4,8,16,24,32(28-29 共2字节)
DWORD biCompression;  // 位图压缩类型,必须是 0(BI_RGB 不压缩 ),  1(BI_RLE8 压缩类型 ),
                                            2(BI_RLE4压缩类型),(30-33 共4字节 )
DWORD biSizeImage;    // 位图数据的大小,以字节为单位 当用BI_RGB时可设置为0 (34-37 4共字节 )  
LONG biXPelsPerMeter; // 位图水平分辨率,像素/米 (38-41 4共字节 )   
LONG biYPelsPerMeter; // 位图垂直分辨率,像素/米  (42-45 4共字节 ) 
DWORD biClrUsed;      // 位图实际使用的颜色表中的颜色所有数,为0使用所有调色板项 (46-49 4共字节 
DWORD biClrImportant; // 位图显示过程中重要的颜色数 为0表示都重要(50-53 共4字节 )
} BITMAPINFOHEADER;

调色板:

typedef struct tagRGBQUAD
{
  unsigned char rgbBlue;
  unsigned char rgbGreen;
  unsigned char rgbRed;
  unsigned char rgbReserved;
}RGBQUAD;

有些位图需要颜色表;有些位图(如真彩色图)则不需要颜色表,颜色表的长度由BITMAPINFOHEADER结构中biBitCount分量决定。对于biBitCount值为1的二值图像,每像素占1bit,图像中只有两种(如黑白)颜色,颜色表也就有21=2个表项,整个颜色表的大小为 2*siezof(RGBQUAD)=2x4=8个字节;对于biBitCount值为8的灰度图像,每像素占8bit,图像中有2^8=256 颜色,颜色表也就有256个表项,且每个表项的R、G、B分量相等,整个颜色表的大小为 256x4 = 1024个字节;而对于biBitCount=24的真彩色图像,由于每像素3个字节中分别代表了R、G、B三分量的值,此时不需要颜色表,因此真彩色图的BITMAPINFOHEADER结构后面直接就是位图数据。

位图数据

由于没有使用调色板,前面一共有14字节+40字节 = 54 =0x36,即位图数据从0x36开始 与 位图头文件中启始位置一致。

每个像素占一个字节,取得这个字节后,以该字节为索引查询相应的颜色,并显示到相应的显示设备上就可以了。

注意:由于位图信息头中的图像高度是正数,所以位图数据在文件中的排列顺序是从左下角到右上角,以行为主序排列的。

计算机图像坐标系是如下方向。