跳到主要内容

文件格式

什么是 BMP?位图格式详解

BMP 是 Windows 的无压缩、无损位图格式。本文介绍它的文件头结构、色深、局限,以及如何让文件变小。

作者: Hemen Dönüştür Editör Ekibi发布日期: 阅读约 7 分钟

BMP 文件格式指南封面图

BMP 是 Windows 世界中最古老、最简单的图片格式之一。BMP 文件通常把像素一行一行地写入磁盘,完全不做压缩。这种简单让它易于读取且无损,同样的简单也让文件变得非常庞大。本文将介绍 BMP 的来历、文件内部的构成、色深和透明度的细节、如今还会在哪里遇到它,以及如何把 BMP 文件转换为更实用的格式。

什么是 BMP?

BMP(bitmap,位图,扩展名 .bmp)是一种基于像素的光栅图像文件格式。技术文档中也称它为 DIB,即设备无关位图(device-independent bitmap)。“设备无关”是指无论图像是在哪种显卡或打印机上创建的,都能以相同的方式解读:文件在自己的文件头和颜色表中携带了解码颜色所需的信息。

根据 Microsoft 的 Win32 文档,位图文件以 BITMAPFILEHEADER 结构开头,接着是 BITMAPINFOHEADER、BITMAPV4HEADER 或 BITMAPV5HEADER,然后是可选的颜色表,最后是像素数据。MIME 类型为 image/bmp。

简要历史:从 Windows 和 OS/2 到今天

BMP 源自 20 世纪 80 年代末 Microsoft 和 IBM 在 Windows 与 OS/2 上的合作。Windows 1.0 时代的位图高度依赖输出设备;设备无关的形式随 1990 年的 Windows 3.0 普及开来。为 OS/2 Presentation Manager 定义的 12 字节 BITMAPCOREHEADER,就是人们至今仍在说“OS/2 BMP”文件的原因。

多年来,这一格式通过在文件头末尾添加字段的方式不断扩展。根据美国国会图书馆的格式说明,第 5 版于 1998 年随 Windows 98 推出,使得在文件中记录 ICC 颜色配置文件成为可能。如今常见的文件头大小如下:

文件头大小主要新增内容
BITMAPCOREHEADER12 字节与 OS/2 1.x 兼容的基本结构
BITMAPINFOHEADER40 字节最常见的文件头,始于 Windows 3.0;压缩和分辨率字段
BITMAPV4HEADER108 字节颜色掩码、alpha 掩码和色彩空间信息
BITMAPV5HEADER124 字节嵌入或链接的 ICC 配置文件、渲染意图

读取程序根据文件头第一个字段中的大小值判断使用的是哪种文件头。这样旧软件可以忽略较新的字段,仍然读取基本信息。

BMP 文件的内部构成

文件头与“BM”签名

每个 BMP 文件都以 14 字节的文件头开始,前两个字节是 ASCII 字符 BM(十六进制 42 4D)。文件头保存文件的总大小,以及像素数据开始位置的字节偏移量。放在 Windows 剪贴板上的 DIB(CF_DIB 格式)省略了这 14 个字节,直接从信息头开始。

信息头

信息头保存宽度、高度、每像素位数(biBitCount)、压缩类型、水平和垂直分辨率(以每米像素数表示),以及颜色表中使用的颜色数。

颜色表(调色板)

在每像素 8 位或更少的图像中,像素不是颜色,而是指向颜色表的索引。在 Microsoft 文档的示例中,一张 16 色的 32x32 位图,像素数组为 32 x 32 x 4 = 4096 位,因为 4 位就足以表示 16 种颜色。

像素数据:自下而上的行与 4 字节对齐

BMP 有两个不同寻常的特点。第一,如果高度为正数,行是自下而上存储的:文件中的第一行是图片的最底下一行。高度为负数时行自上而下存储,但这样的图像不能压缩。第二,每一行都会被填充到 4 字节的整数倍。Microsoft 给出的行长度(stride)公式为:

stride = ((width * bitCount + 31) & ~31) >> 3
imageSize = |height| * stride

对于一张 24 位的 1920x1080 图片,每行为 1920 x 3 = 5,760 字节(本身就是 4 的倍数),因此像素数据为 5,760 x 1,080 = 6,220,800 字节。加上 54 字节的文件头,文件约为 6.2 MB。同样的图片保存为 JPG,通常只有其中很小的一部分。

色深、压缩与透明度

BITMAPV5HEADER 文档定义了每像素 1、4、8、16、24 和 32 位(值为 0 表示色深来自嵌入的 JPEG 或 PNG 数据)。1 位是黑白,4 位是 16 色,8 位是 256 色调色板。24 位时,每个像素是按蓝、绿、红顺序排列的三个字节。

压缩字段可以取以下值:

  • BI_RGB:无压缩。实际中绝大多数 BMP 文件都是这种。
  • BI_RLE8 和 BI_RLE4:用于 8 位和 4 位调色板图像的简单游程编码。对大面积纯色区域有用,对照片几乎无效。
  • BI_BITFIELDS:并不是压缩;而是用掩码定义红、绿、蓝各位在 16 位和 32 位像素中的位置(例如 RGB 565)。
  • BI_JPEG 和 BI_PNG:允许在位图中嵌入 JPEG 或 PNG 数据。通用看图软件很少支持。

透明度是 BMP 最不一致的地方。V4 和 V5 文件头中的 alpha 掩码可以把 32 位像素的第四个字节定义为不透明度,但在传统的 32 位 BMP 中,这个字节被描述为未使用,许多程序会忽略它。所以,一张 32 位 BMP 在一个程序中显示为透明、在另一个程序中却是黑底,一点也不稀奇。如果需要透明度,PNG 要稳妥得多。

在系统、浏览器和软件中的支持

BMP 几乎在任何地方都能打开。Windows 内置的看图工具和画图、macOS 的“预览”以及常见的 Linux 看图软件都能读取它。MDN 的图片格式指南列出,所有版本的 Chrome、Edge、Firefox、Opera 和 Safari 都支持 BMP。该指南也强调,与 PNG 或 JPG 相比,无压缩的 BMP 文件非常大,一般应避免用于网站内容。

如今 BMP 用在哪里?

  • Windows 应用资源和旧版软件:工具栏图片、安装向导图形和部分游戏素材仍然是 BMP。
  • 嵌入式系统和微控制器:带显示屏的设备不需要 JPEG 解码器,像素数据可以直接复制到屏幕上。
  • 工业相机、扫描仪和测试工具:需要原始、无损的输出时,BMP 是一种简单的中间格式。
  • 教学:文件头只有几十个字节,BMP 常常是图像处理课程中学生读写的第一种格式。

优点与缺点

优点缺点
无损;像素值永远不变无压缩,因此文件非常大
读写极其简单,不消耗 CPU透明度支持不一致
几乎所有操作系统和浏览器都能打开元数据支持较弱(EXIF、描述)
调色板模式适合资源有限的设备不适合网页、电子邮件和上传表单

常见问题及解决方法

文件太大,无法用邮件发送或上传

这是最常见的问题。对于照片和扫描件,把 BMP 转换为 JPG 通常能把大小缩小一个数量级甚至更多。对于屏幕截图、图表或任何带文字的内容,把 BMP 转换为 PNG 更好:PNG 同样是无损的,但经过压缩,也不会像 JPG 那样在锐利边缘周围产生噪点。

32 位 BMP 显示为黑色背景

程序无法识别或错误解读了 alpha 字节。转换为 PNG 通常可以解决。转换为没有透明度的 JPG 时,透明区域会被填充为白色或你选择的颜色。

图片上下颠倒或歪斜

在自己编写的读取程序中,这通常源于两个错误:忽略了行是自下而上存储的,或者没有跳过每行末尾的填充字节。使用上面的 stride 公式并检查高度的正负号,就能避免这两个问题。

某个程序拒绝打开 BMP

一些简单的读取程序不支持采用 RLE 压缩、BI_BITFIELDS 或嵌入 JPEG/PNG 数据的 BMP 文件。重新保存为无压缩的 24 位 BMP 或转换为 PNG,就能消除兼容性问题。

转换技巧

  • 照片用 JPG,图形用 PNG:从 BMP 转出时同样适用这条常规。用于网页时,也可以在图片格式转换工具中选择 WebP 或 AVIF。
  • 保持较高的画质:由于 BMP 是无损的,85-90% 的 JPG 画质得到的结果与原图很难区分。
  • 需要时缩小:如果文件仍然很大,可以缩小像素尺寸,或使用图片压缩达到目标大小。
  • 反方向转换:如果嵌入式设备或旧程序需要 BMP,请在图片格式转换工具中选择 BMP 作为目标格式。我们的工具会生成标准的无压缩 24 位 BMP;透明区域会被合并到你选择的背景色上。

我们的 BMP 转换页面在你的浏览器中运行:文件不会上传,也不会离开你的设备。

常见问题

BMP 和 DIB 是一回事吗?

实际上是的。DIB 是 Windows 在内存和剪贴板中使用的设备无关位图结构;BMP 文件就是在这个结构前面加上 14 字节的文件头。

BMP 是无损的吗?

是的。无压缩和 RLE 压缩的 BMP 文件都会精确保留像素值。唯一的例外是少见的嵌入 JPEG 数据的 BMP。

BMP 转 PNG 会损失画质吗?

不会。PNG 同样是无损的;图片保持完全一致,只是因为经过压缩而变小。

可以在网站上使用 BMP 吗?

浏览器能显示 BMP,但文件毫无必要地大,会拖慢页面。网页请使用 JPG、PNG、WebP 或 AVIF。

BMP 支持透明度吗?

32 位 BMP 理论上可以携带 alpha 通道,但软件对它的支持并不一致。需要透明度时,PNG 是更稳妥的选择。

参考资料

相关转换工具

全部文章