图片 bmp 格式详解

1 概述

BMP(Bitmap-File)图片文件格式,又称为 Bitmap (位图)或是 DIB(Device-Independent Device,设备无关位图),是 Windows 系统中广泛使用的图像文件格式。

由于它可以不作任何变换的保存图像像素域的数据,因此成为我们取得 RAW 数据的重要来源。Windows 的图形用户界面(graphical user interfaces)也在它的内建图像子系统 GDI 中对 BMP 格式提供了支持。

BMP 位图文件默认的文件扩展名是 BMP 或者 bmp(有时它也会以 .DIB 或 .RLE 作扩展名)

2 BMP 文件结构

BMP 文件的数据按照从文件头开始的先后顺序分为四个部分:

  1. 位图文件头(bmp file header): 提供文件的格式、大小等信息
  2. 位图信息头(bitmap information):提供图像数据的尺寸、位平面数、压缩方式、颜色索引等信息
  3. 调色板(color palette):可选,如使用索引来表示图像,调色板就是索引与其对应的颜色的映射表
  4. 位图数据(bitmap data):图像数据区

一个常见的 BMP 文件数据表如下:

数据段名称 大小(byte)
位图文件头 14
位图信息头 40
调色板 由 biBitCount 决定
位图数据 由图片大小和颜色决定

2.1 位图文件头

Windows 为 bmp 位图文件图定义了如下的结构体:

typedef struct tagBITMAPFILEHEADER { 
    UINT16 bfType;        // 2 Bytes,文件类型,必须为 "BM",即 0x424D
    DWORD bfSize;         // 4 Bytes,整个 BMP 文件的大小,单位为字节
    UINT16 bfReserved1;   // 2 Bytes,保留位置为 0
    UINT16 bfReserved2;   // 2 Bytes,保留位置为 0
    DWORD bfOffBits;      // 4 Bytes,文件起始位置到图像位图数据的字节偏移量
} BITMAPFILEHEADER;

以下面普通 24 位位图为例:

图片 bmp 格式详解_第1张图片

以字节向后数:

  • 前 1-2 字节:0x424d = ‘BM’,表示这是 Windows 支持的位图格式
  • 3 - 6 字节:BMP 图片为小端方式存储,0x002A3036 = 2764854 kb ≈ 2.6M
  • 7 - 10 字节:保留为,置为 0
  • 11 - 14:0x00000036 = 54,实例 BMP 文件没有调色板,从文件头到位图数据偏移 54 个字节

2.2 位图信息头

位图信息头一般为 40 个字节,各字段含义如表格所示:

变量名 大小 说明
biSize 4 Bytes BMP_INFOHEADER 表示所需要的字节数(以字节为单位)
biWidth 4 Bytes 说明图像的宽度(以像素为单位)
biHeight 4 Bytes 说明图像的高度(以像素为单位)
biPlanes 2 Bytes 为目标设备说明位面数,其值总设置为 1
biBitCount 2 Bytes 一个像素点占几位,其值可为 1、4、8、16、24 或 32
biCompression 4 Bytes 图像数据的压缩类型,详解见表后
biSizeImage 4 Bytes 图像的大小,与压缩类型相关,见下文
biXPelsPerMeter 4 Bytes 水平分辨率
biYPelsPerMeter 4 Bytes 垂直分辨率
biClrUsed 4 Bytes 位图实际使用的调色板索引数,0 表示使用所有的调色板索引
biClrImportant 4 Bytes 对图像显示有重要影响的颜色索引的数目,如果是 0 表示都重要。
biCompression 图像数据的压缩类型

取值范围为:

  • BI_RGB 不压缩(最常用)
  • BI_RLE8 8 比特游程编码(BLE),只用于 8 位位图
  • BI_RLE4 4 比特游程编码(BLE),只用于 4 位位图
  • BI_BITFIELDS 比特域(BLE),只用于 16/32 位位图
  • BI_JPEG 位图包含 JPEG,只用于打印机
  • BI_PNG 位图包含 PNG,只用于打印机

biSizeImage 图像大小与压缩类型相关,当压缩类型为 BI_RGB 不压缩时为 0

以下面的实例分析位图信息头,见蓝色部分:

图片 bmp 格式详解_第2张图片

  • 1 - 4 字节:0x00000028 = 40 字节,表示该位图信息头占用 40 个字节。
  • 5 - 8 字节:位图宽度为 0x00000500 = 1280 像素
  • 9 - 12 字节:位图高度为 0x000002D0 = 720 像素
  • 13 - 14 字节:biPlanes,0x0001 值总为 1
  • 15 - 16 字节:biBitCount,0x0018 = 24,说明一个像素占用 24 字节,为 24 位位图
  • 17 - 20 字节:biCompression,0x00000000 = 0 ,0 表示本图像不压缩
  • 21 - 24 字节:biSizeImage,图像大小,因为使用 BI_RGB 不压缩所以值为 0
  • 25 - 28 字节:水平分辨率,缺省
  • 29 - 32 字节:垂直分辨率,缺省
  • 33 - 36 字节:biClrUsed,0 表示使用所有的调色板索引
  • 37 - 40 字节:biClrImportant,表示所有颜色索引都重要

2.3 调色板

BMP 调色板结构体可以定义如下:

typedef struct _tagRGBQUAD
{
    BYTE  rgbBlue;       // 指定蓝色强度
    BYTE  rgbGreen;      // 指定绿色强度
    BYTE  rgbRed;        // 指定红色强度
    BYTE  rgbReserved;   // 保留,设置为0
} RGBQUAD;

调色板其实是一张映射表,标识颜色索引号与其代表的颜色的对应关系。它在文件中的布局就像一个二维数组 palette[N][4],其中 N 表示总的颜色索引数,每行的四个元素分别表示该索引对应的 B、G、R 和 Alpha 的值,每个分量占一个字节。如不设透明通道时,Alpha 为 0。

2.4 BMP 位图数据

位图数据记录了位图的每一个像素值,记录顺序是在扫描行内是从左到右,扫描行之间是从下到上。位图的一个像素值所占的字节数:

  • 当 biBitCount = 1 时,8 个像素占 1 个字节;
  • 当 biBitCount = 4 时,2 个像素占 1 个字节;
  • 当 biBitCount = 8 时,1 个像素占 1 个字节;
  • 当 biBitCount = 24 时, 1 个像素占 3 个字节;

当扫描取到一个字节后,以该字节为索引查询相应的颜色,并显示到相应的显示设备上即可。

位图的高度为负数时,扫描顺序相反,从右到左,从上到下,即从右上角扫描到左下角。

你可能感兴趣的:(音视频基础)