BMP(Bitmap,位图)是微软定义的一种无损位图格式,其文件结构按固定顺序分段存储,核心分为三大块:文件头(Bitmap File Header)、信息头(DIB Header/Info Header)、像素数据(Pixel Data),部分场景还会包含调色板(Color Palette)。

以下是 BMP 文件结构的详细拆解(以最常用的 24 位无压缩 BMP 为例):
一、整体结构总览
| 段名称 | 字节大小(典型值) | 核心作用 |
|---|---|---|
| 文件头 | 14 字节 | 标识文件类型、总大小、数据偏移 |
| 信息头 | 40 字节(BITMAPINFOHEADER) | 描述图像尺寸、位深度、压缩方式等 |
| 调色板 | 0 ~ N 字节 | 仅 8 位/4 位等低色深 BMP 需用 |
| 像素数据 | 可变(按对齐规则) | 存储图像的像素颜色数据 |
注:信息头有多个版本(如 BITMAPCOREHEADER 仅 12 字节),但 BITMAPINFOHEADER(40 字节) 是最通用的版本,下文以此为准。
二、各段详细解析
1. 文件头(Bitmap File Header,14 字节)
纯文件级元信息,与图像内容无关,结构如下:
| 偏移(字节) | 字段名 | 数据类型 | 大小(字节) | 说明 |
|---|---|---|---|---|
| 0 | bfType | 无符号短整型 | 2 | 标识 BMP 文件,固定值 0x424D(ASCII 为 BM),验证是否为 BMP 文件 |
| 2 | bfSize | 无符号长整型 | 4 | 文件总字节数(小端序),包含所有段的总大小 |
| 6 | bfReserved1 | 无符号短整型 | 2 | 保留字段,固定为 0 |
| 8 | bfReserved2 | 无符号短整型 | 2 | 保留字段,固定为 0 |
| 10 | bfOffBits | 无符号长整型 | 4 | 像素数据的起始偏移量(即文件头+信息头+调色板的总字节数) |
小端序(Little Endian):BMP 所有多字节数值均按「低字节在前、高字节在后」存储(如数值 0x12345678 存储为 0x78 0x56 0x34 0x12)。
2. 信息头(BITMAPINFOHEADER,40 字节)
描述图像的核心属性,是解析 BMP 的关键:
| 偏移(字节) | 字段名 | 数据类型 | 大小(字节) | 说明 |
|---|---|---|---|---|
| 14 | biSize | 无符号长整型 | 4 | 信息头本身的字节数(BITMAPINFOHEADER 固定为 40) |
| 18 | biWidth | 整型 | 4 | 图像宽度(像素),正数 |
| 22 | biHeight | 整型 | 4 | 图像高度(像素): ✅ 负数:从上到下绘制(主流方式) ✅ 正数:从下到上绘制 |
| 26 | biPlanes | 无符号短整型 | 2 | 色彩平面数,固定为 1(BMP 仅支持 1 个平面) |
| 28 | biBitCount | 无符号短整型 | 2 | 位深度(每个像素的位数): ✅ 1/4/8 位:需调色板 ✅ 24 位:真彩色(无Alpha) ✅ 32 位:真彩色+Alpha |
| 30 | biCompression | 无符号长整型 | 4 | 压缩方式: ✅ 0(BI_RGB):无压缩(最常用) ✅ 1(BI_RLE8):8位RLE压缩 ✅ 2(BI_RLE4):4位RLE压缩 |
| 34 | biSizeImage | 无符号长整型 | 4 | 像素数据的总字节数(无压缩时可填 0,或等于实际大小) |
| 38 | biXPelsPerMeter | 整型 | 4 | 水平分辨率(像素/米),默认 2835(96 DPI) |
| 42 | biYPelsPerMeter | 整型 | 4 | 垂直分辨率(像素/米),默认 2835(96 DPI) |
| 46 | biClrUsed | 无符号长整型 | 4 | 调色板使用的颜色数: ✅ 0:使用全部颜色(低色深时自动计算) |
| 50 | biClrImportant | 无符号长整型 | 4 | 重要颜色数: ✅ 0:所有颜色都重要 |
3. 调色板(Color Palette,可选)
仅 位深度 ≤ 8 位 的 BMP 需要(如 8 位灰度图、4 位索引图),24/32 位真彩色 BMP 无调色板(直接存储像素颜色)。
调色板每个条目占 4 字节(BGRA 格式,Alpha 固定为 0),结构为:
| 字节 0 | 字节 1 | 字节 2 | 字节 3 |
|---|---|---|---|
| 蓝色(B) | 绿色(G) | 红色(R) | 保留(0) |
例如:调色板中一个红色条目为 0x00 0x00 0xFF 0x00。
4. 像素数据(Pixel Data)
BMP 核心数据区,存储每个像素的颜色,有两个关键规则:
(1)颜色格式
- 24 位 BMP:每个像素占 3 字节,顺序为 B(蓝)→ G(绿)→ R(红)(无 Alpha);
- 32 位 BMP:每个像素占 4 字节,顺序为 B → G → R → A(Alpha);
- 8 位 BMP:每个像素占 1 字节,值为调色板的索引;
- (对比:Canvas 读取的像素是 RGBA 格式,转换时需反转 RGB 顺序)。
(2)行对齐规则(核心!)
BMP 要求每行像素数据的字节数必须是 4 的倍数,不足时在行尾补 0(填充字节)。
行字节数计算公式:
行字节数 = Math.floor((位深度 × 宽度 + 31) / 32) × 4
示例:
- 24 位、宽度 100 像素:
(24×100 +31)/32 ×4 = (2400+31)/32×4 = 75.96875×4 → 76×4=304 字节(实际像素占 300 字节,补 4 个 0); - 24 位、宽度 101 像素:
(24×101+31)/32×4 = 2455/32×4=76.71875×4→77×4=308 字节(补 5 个 0?不:24×101=2424,2424%4=0 → 无需补,行字节数=2424)。
(3)存储顺序
像素数据按「行倒序」存储(除非 biHeight 为正数):
- 若 biHeight 为负数:先存第一行,再存第二行(从上到下);
- 若 biHeight 为正数:先存最后一行,再存倒数第二行(从下到上)。
三、示例:24 位无压缩 BMP 结构(宽 2px,高 1px)
| 段 | 偏移 | 内容(十六进制) | 说明 |
|---|---|---|---|
| 文件头 | 0-13 | 42 4D 36 00 00 00 00 00 00 00 36 00 00 00 | BM + 总大小54 + 偏移54 |
| 信息头 | 14-53 | 28 00 00 00 02 00 00 00 FF FF FF FF 01 00 18 00 00 00 00 00 0C 00 00 00 13 0B 00 00 13 0B 00 00 00 00 00 00 00 00 00 00 | 40字节 + 宽2 + 高-1 + 24位 + 无压缩 |
| 像素数据 | 54-59 | FF 00 00 00 00 FF 00 00 00 | 像素1(红:00 00 FF)+ 像素2(绿:00 FF 00)+ 补0(行对齐) |
总大小:14+40+6=60 字节(0x36),像素数据 6 字节(2×3),无需补对齐字节。
四、关键总结
- BMP 核心是「头信息 + 对齐后的像素数据」,头信息决定解析规则;
- 24 位 BMP 无调色板、无 Alpha,像素顺序为 BGR;
- 行对齐是最容易踩坑的点,必须保证每行字节数为 4 的倍数;
- 多字节数值均为小端序,与日常的大端序(网络字节序)相反。
这也是上文中 PNG 转 BMP 代码的核心依据:按上述结构组装字节,就能生成标准的 BMP 文件。
707

被折叠的 条评论
为什么被折叠?



