BMP取自位图Bitmap的缩写,也称为DIB(与设备无关的位图),是一种独立于显示器的位图数字图像文件格式。常见于微软视窗和OS/2操作系统,Windows GDI API内部使用的DIB数据结构与 BMP 文件格式几乎相同。
图像通常保存的颜色深度有2(1位)、16(4位)、256(8位)、65536(16位)和1670万(24位)种颜色(其中位是表示每点所用的数据位)。8位图像可以是索引彩色图像外,也可以是灰阶图像。表示透明(英语:transparency (graphic))的alpha通道也可以保存在一个类似于灰阶图像的独立文件中。带有集成的alpha通道的32位版本已经随着Windows XP出现,它在视窗的登录和主题系统中都有使用。
BMP文件通常是不压缩的,所以它们通常比同一幅图像的压缩图像文件格式要大很多。例如,一个800×600的24位几乎占据1.4MB空间。因此它们通常不适合在因特网或者其他低速或者有容量限制的介质上进行传输。
根据颜色深度的不同,图像上的一个像素可以用一个或者多个字节表示,它由n/8所确定(n是位深度,1字节包含8个数据位)。图片浏览器等基于字节的ASCII值计算像素的颜色,然后从调色板中读出相应的值。更为详细的信息请参阅下面关于位图文件的部分。
n位2n种颜色的包含调色板的位图近似字节数可以用下面的公式计算:
BMP文件大小
,其中高度(height)和宽度(width)都以像素为单位。需要注意的是上面公式中的54是位图文件的文件头(英语:Header (information technology)),
是彩色调色板的大小。如果位图文件不包含调色板,如24位,32位位图,则位图的近似字节数可以用下面的公式计算:BMP文件大小
,其中高度(height)和宽度(width)都以像素为单位。另外需要注意的是这是一个近似值,对于n位的位图图像来说,尽管可能有最多
种颜色,一个特定的图像可能并不会使用这些所有的颜色。由于彩色调色板仅仅定义了图像所用的颜色,所以实际的彩色调色板将小于 。如果想知道这些值是如何得到的,请参考下面文件格式的部分。
由于存储算法本身决定的因素,根据几个图像参数的不同计算出的大小与实际的文件大小将会有一些细小的差别。
位图图像文件由若干大小固定(文件头)和大小可变的结构体按一定的顺序构成。由于该文件格式几经演进,这些结构体的版本也很多。
位图文件由以下结构体依次构成:
下面的部分将会详细地描述位图文件中保存的数据。需要注意的是这是标准位图的文件格式,其他一些位图图像可能根据生成文件的应用程序不同所使用格式可能会有细微的区别。
这部分数据块位于文件开头,用于进行文件的识别。典型的应用程序会首先普通读取这部分数据以确保的确是位图文件并且没有损坏。所有的整数值都以小端序存放(即最低有效位前置)。
这部分告诉应用程序图像的详细信息,在屏幕上显示图像将会使用这些信息,它从文件的第15个字节开始。
这部分数据块对应了Windows和OS/2中的内部使用的头结构以及其它一些版本的变体。但所有版本均以一个DWORD位(32位)开始,用以说明该数据块的大小,使得应用程序能够根据这个大小来区分该图像实际使用了哪种版本的DIB头结构。
存在多种版本的头结构的原因是微软对DIB格式进行过多次扩展。下表即为所有不同版本的DIB头:
BITMAPCOREHEADER之后的版本都只是在前一版本结构末尾追加字段。
出于兼容性的考量,大多数应用程序使用较旧版本的DIB头保存文件。在不考虑OS/2的情况下,目前通用的格式为BITMAPINFOHEADER版本,内容在下表中列出。除非有特殊说明,其中所有值均为无符号整数。
注意:BI_RGB图像的图像大小字段可以为0。
压缩方法字段(字节#30-33)的有效值如下表:
注意:BI_JPEG和BI_PNG仅对打印机驱动有效,不支持屏幕渲染。
除此之外,OS/2的BITMAPCOREHEADER头也不鲜见:
注意:OS/2 BITMAPCOREHEADER的位图都是未压缩的,而且不能是16或32位/像素。OS/2 BITMAPCOREHEADER中的所有值均为无符号整数。
这部分定义了图像中所用的颜色。如上所述,位图图像一个像素接着一个像素储存,每个像素使用一个或者多个字节的值表示,所以调色板的目的就是要告诉应用程序这些值所对应的实际颜色。
典型的位图文件使用RGB彩色模型。在这种模型中,每种颜色都是由不同强度(从0到最大强度)的红色(R)、绿色(G)和蓝色(B)组成的,也就是说,每种颜色都可以使用红色、绿色和蓝色的值所定义。
在位图文件的实现中,调色板可以包含很多条目,条目个数就是图像中所使用的颜色的个数。
typedef struct tagRGBQUAD { BYTE rgbBlue; BYTE rgbGreen; BYTE rgbRed; BYTE rgbReserved;} RGBQUAD;