BMP格式
1. 简介
BMP 格式是 Windows 下最简单的图像存储格式,它支持图像以每像素 比特表示。BMP 格式也支持 比特每像素的游程算法压缩图像。
2. 格式
BMP 文件基本结构如下:

其详细结构如下:

2.1 File Header
BMP 文件中的 File Header 包含一个 BITMAPFILEHEADER
结构,主要用来识别文件格式,其包含的字段如下表所示:
字段名 | 大小(Bytes) | 说明 |
---|---|---|
bfType |
存储两个字符「BM」用于验证文件类型 | |
bfSize |
存储该文件大小 | |
bfReserved1 |
未使用(值必须为 ) | |
bfReserved2 |
未使用(值必须为 ) | |
bfOffBits |
存储像素数据开始处的偏移大小 |
2.2 Image Header
File Header 后紧接着为 Image Header。Image Header 可以为两种不同结构的其中一种:BITMAPINFOHEADER
和 BITMAPCOREHEADER
。Windows 下 BMP 文件一般使用的是 BITMAPINFOHEADER
结构。BMP 中没有专门的子段来指明 Image Header 使用的结构,因此只能通过比较 IMage Header 的大小来判断其使用的结构。BITMAPINFOHEADER
结构至少为 Byters 大小,而 BITMAPCOREHEADER
结构只有 Bytes 大小。
BITMAPINFOHEADER
结构包含的字段如下表所示:
字段名 | 大小(Bytes) | 说明 |
---|---|---|
biSize |
Image Header 大小(至少 ) | |
biWidth |
图像宽度 | |
biHeight |
图像高度 | |
biPlanes |
值必须为 | |
biBitCount |
每像素所用比特数—— | |
biCompression |
压缩类型——BI_RGB=0,BI_RLE8=1,BI_RLE4=2,BI_BITFIELDS=3 |
|
biSizeImage |
图像大小——如果没有压缩则该值为 | |
biXPelsPerMeter |
X 轴首选分辨率(每米) | |
biYPelsPerMeter |
Y 轴首选分辨率(每米) | |
biClrUsed |
Color Table 中实际使用的色彩项数目 | |
biClrImportant |
重要的色彩数目 |
BITMAPCOREHEADER
结构包含的字段如下表所示:
字段名 | 大小(Bytes) | 说明 |
---|---|---|
bcSize |
Image Header 大小(值必须为 ) | |
bcWidth |
图像宽度 | |
bcHeight |
图像高度 | |
bcPlanes |
值必须为 | |
bcBitCount |
每像素所用比特数—— |
【注】如果 BMP 文件的 Image Header 使用 BITMAPCOREHEADER
结构,像素数据则不能被压缩。
2.3 Color Table
Image Header 后紧接着为 Color Table。Color Table 也称为 Color Palette(调色板)可以为三种格式中的一种:前两种主要用于将像素值映射到 RGB 颜色值,适用于每像素比特数为 的情况(由 Image Header 中的 biBitCount
或 bcBitCount
字段指定)。
- 对于 Windows 下的 BMP 文件,Color Table 为由 个
RGBQUAD
项构成的数组,每个RGBQUAD
项包含的字段如下表所示:
字段名 | 大小(Bytes) | 说明 |
---|---|---|
rgbBlue |
蓝色分量值 | |
rgbGreen |
绿色分量值 | |
rgbRed |
红色分量值 | |
rgbReserved |
未使用(值必须为 ) |
- 对于 OS/2 下的 BMP 文件,Color Table 为由 个
RGBTRIPLE
项构成的数组,每个RGBTRIPLE
项包含的字段如下表所示:
字段名 | 大小(Bytes) | 说明 |
---|---|---|
rgbtBlue |
蓝色分量值 | |
rgbtGreen |
绿色分量值 | |
rgbtRed |
红色分量值 |
最后一种格式是当 BITMAPINFOHEADER
结构中的 BiCompression
字段取值为 BI_BITFIELDS(3)
时,在 RGBQUAD
数组前多出了一个掩码结构。比如以 位的 BMP 图像为例,三个掩码均为 位,即 Bytes。
掩码字段 | 掩码值 |
---|---|
Red | |
Green | |
Blue |
掩码字段主要用于明确哪些比特位分别用来表示 Red、Green、Blue 分量。对于 位的 BMP 图像来说,每个掩码字段中连续的 比特(必须是连续且相互无交叉的)用来表明每个分量使用到的比特位置。
【注】对于 biCompression
字段没有设定为值 BI_BITFIELDS
的 位的 BMP 图像,没有 Color Table。
2.4 Pixel Data
Pixel Data 通常直接接在 Color Table 或 Image Header 后面,但有时为了保证对齐也会先填充一些字节再接上 Pixel Data。所以必须使用 bfOffBits
字段来明确 Pixel Data 的起始偏移。像素行是由底向上排列在 Pixel Data 中,即 Pixel Data 第一行为图像的最底行,以此类推。行数由 biHeight
或 bcHeight
决定,行大小则由 biBitCount
和 biWidth
或 bcBitCount
和 bcWidth
共同决定。每行大小都按字节对齐到 的倍数,具体计算公式如下:
像素数据格式取决于 biBitCount
或 bcBitCount
:
-
或 比特每像素:每个数据字节被分成 或 部分,每部分表示 Color Table 中的索引值。
-
比特每像素:每个数据字节表示 Color Table 中的索引值。
-
比特每像素:
- 如果
BITMAPINFOHEADER
中的biCompression
为BI_RGB(0)
,则每个颜色分量使用 比特表示,最高比特位保留。
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 Red Blue Green
- 如果
BITMAPINFOHEADER
中的biCompression
为BI_BITMAP
,三个 Bytes 的掩码指明了每个颜色分量使用到的比特。三个掩码依次为 Red、Blue、Green。
-
对于 比特每像素:每个像素使用三个连续的字节依次表示 Blue、Green、Red 分量的颜色值。在其他大多数图像格式中,这三个分量的顺序往往是反过来的,即 Red、Green、Blue。
-
对于 比特每像素:
- 如果
BITMAPINFOHEADER
中的biCompression
为BI_RGB(0)
,则三个低位的字节依次表示 Blue、Green、Red,最高位字节未使用(相当于是在 比特每像素基础上再浪费一个字节)。- 如果
BITMAPINFOHEADER
中的biCompression
为BI_BITMAP
,三个 Bytes 的掩码指明了每个颜色分量使用到的比特。三个掩码依次为 Red、Blue、Green。
3. 算法
对于 比特每像素,BMP 格式支持游程编码压缩。以下情况表示 BMP 格式使用了游程编码:
- 比特每像素:如果
BITMAPINFOHEADER
中的biCompression
为BI_RLE4(2)
。 - 比特每像素:如果
BITMAPINFOHEADER
中的biCompression
为BI_RLE8(1)
。
3.1 RLE4
在 RLE4 压缩算法中,压缩数据被切分称 Bytes 的数值对,第二个字节为像素值对,第一个字节给出了像素值出现的数目。对于第二个字节的像素值对,高四位表示第奇数个像素的像素值,低四位表示第偶数个像素的像素值。比如,在 比特每像素的 BMP 图像中,<> 数值对解码后为:
第一个字节如果为 则表示转义码。
- <>:表示新的图像行开始。
- <>:表示图像像素数据结束。
- <>:表示改变当前图像位置,接下来两个无符号字节分别表示跳过的列数和行数。这个转义码主要用于跳过大片矩形的 块。
- <>:表示未压缩的像素字节数,接下来 个字节都是未压缩的像素对字节,高四位 为第一个像素值,低四位 为第二个像素值。这个转义码主要用于存储未压缩的数据。(注意: 必须为 的倍数,否则会在最后填充字节)
3.2 RLE8
在 RLE8 压缩算法中,压缩数据被切分称 Bytes 的数值对,第二个字节为像素值,第一个字节则给出了像素值连续出现的数目。比如,在 比特每像素的 BMP 图像中,<> 数值对解码后为:
第一个字节如果为 则表示转义码。
- <>:表示新的图像行开始。
- <>:表示图像像素数据结束。
- <>:表示改变当前图像位置,接下来两个无符号字节分别表示跳过的列数和行数。这个转义码主要用于跳过大片矩形的 块。
- <>:表示未压缩的像素字节数,接下来 个字节都是未压缩的像素字节,无需解压。这个转义码主要用于存储未压缩的数据。
附录
- BMP file format
- 《Compressed Image File Formats JPEG, PNG, GIF, XBM, BMP》 by John Miano
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!