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 字节)

纯文件级元信息,与图像内容无关,结构如下:

偏移(字节)字段名数据类型大小(字节)说明
0bfType无符号短整型2标识 BMP 文件,固定值 0x424D(ASCII 为 BM),验证是否为 BMP 文件
2bfSize无符号长整型4文件总字节数(小端序),包含所有段的总大小
6bfReserved1无符号短整型2保留字段,固定为 0
8bfReserved2无符号短整型2保留字段,固定为 0
10bfOffBits无符号长整型4像素数据的起始偏移量(即文件头+信息头+调色板的总字节数)

小端序(Little Endian):BMP 所有多字节数值均按「低字节在前、高字节在后」存储(如数值 0x12345678 存储为 0x78 0x56 0x34 0x12)。

2. 信息头(BITMAPINFOHEADER,40 字节)

描述图像的核心属性,是解析 BMP 的关键:

偏移(字节)字段名数据类型大小(字节)说明
14biSize无符号长整型4信息头本身的字节数(BITMAPINFOHEADER 固定为 40)
18biWidth整型4图像宽度(像素),正数
22biHeight整型4图像高度(像素):
✅ 负数:从上到下绘制(主流方式)
✅ 正数:从下到上绘制
26biPlanes无符号短整型2色彩平面数,固定为 1(BMP 仅支持 1 个平面)
28biBitCount无符号短整型2位深度(每个像素的位数):
✅ 1/4/8 位:需调色板
✅ 24 位:真彩色(无Alpha)
✅ 32 位:真彩色+Alpha
30biCompression无符号长整型4压缩方式:
✅ 0(BI_RGB):无压缩(最常用)
✅ 1(BI_RLE8):8位RLE压缩
✅ 2(BI_RLE4):4位RLE压缩
34biSizeImage无符号长整型4像素数据的总字节数(无压缩时可填 0,或等于实际大小)
38biXPelsPerMeter整型4水平分辨率(像素/米),默认 2835(96 DPI)
42biYPelsPerMeter整型4垂直分辨率(像素/米),默认 2835(96 DPI)
46biClrUsed无符号长整型4调色板使用的颜色数:
✅ 0:使用全部颜色(低色深时自动计算)
50biClrImportant无符号长整型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-1342 4D 36 00 00 00 00 00 00 00 36 00 00 00BM + 总大小54 + 偏移54
信息头14-5328 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 0040字节 + 宽2 + 高-1 + 24位 + 无压缩
像素数据54-59FF 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),无需补对齐字节。

四、关键总结

  1. BMP 核心是「头信息 + 对齐后的像素数据」,头信息决定解析规则;
  2. 24 位 BMP 无调色板、无 Alpha,像素顺序为 BGR;
  3. 行对齐是最容易踩坑的点,必须保证每行字节数为 4 的倍数;
  4. 多字节数值均为小端序,与日常的大端序(网络字节序)相反。

这也是上文中 PNG 转 BMP 代码的核心依据:按上述结构组装字节,就能生成标准的 BMP 文件。

Logo

助力广东及东莞地区开发者,代码托管、在线学习与竞赛、技术交流与分享、资源共享、职业发展,成为松山湖开发者首选的工作与学习平台

更多推荐