目录
一、概述
二、.bmp
格式文件详解
2.1 位图文件头
2.2 位图信息头
2.3 调色板
2.4 位图数据
三、位图的其他知识
3.1 压缩的位图
一、概述
bmp
是英文Bitmap(位图)的简写,它是Windows操作系统中的标准图像文件格式,随着windows的流行,bmp
位图格式被广泛应用。
位图按照是否与设备相关分类可以分为:设备相关位图DDB(device-dependent bitmap)、设备无关位图DIB(device-independent bitmap)。
按照像素深度分类可以分为:1bit
位图(2色)、4bit
位图(16色)、8bit
位图(256色)、16bit
位图(65536色-高彩色)、24bit
位图(1670万色-真彩色)、32bit
位图(1670万色-增强型真彩色)。
二、.bmp
格式文件详解
.bmp
位图文件由四个部分组成:
- 位图文件头(bitmap-file header)
- 位图信息头(bitmap-information header)
- 调色板(color table)
- 位图数据(图像数据,Data Bits 或Data Body)阵列
下面对文件结构的这几个部分进行详细的介绍。
本节举例说明的位图是100*100的4bit位图,在windows查看其属性如下:
2.1 位图文件头
Windows BMP位图文件头共14个字节,包含了文件类型标志、文件大小等信息,定义的结构体也比较,详细说明如下:
- 结构体:
typedef struct BITMAPFILEHEADER /* size: 40 */
{
unsigned short bfType; // 文件的类型,该值必需是0x4D42,也就是字符'BM'。
unsigned long bfSize; // 位图文件的大小,用字节为单位
unsigned short bfReserved1;// 保留,必须设置为0
unsigned short bfReserved2;// 保留,必须设置为0
unsigned long bfOffBits;// 位图数据距离文件开头偏移量,用字节为单位
} BITMAPFILEHEADER;
- 结构体字段详细说明:
- 位图文件举例
上图是100*100的4bit位图
文件使用十六进制查看的截图。结合前面的结构体说明,
第0-1的2个字节是0x4d42
(红色框),表示这是.bmp
文件;
第2-5的4个字节数值为0x14c8
(绿色框),换算十进制为5320
,说明图片大小为5320
字节,与前面的位图属性大小对应上;
第6-9的4个字节都是保留的,且必须填0;
第a-d的4个字节数值为0x76
,换算十进制为118
,说明位图数据距离文件起始位置118个字节,其实就是位图文件头
(14字节)、位图信息头
(40字节)、调色板
(16色*4=64字节)三个部分占用的字节数。
2.2 位图信息头
Windows BMP位图信息头共40个字节,包含了文件类型标志、文件大小等信息,定义的结构体也比较,详细说明如下:
- 结构体
typedef struct WINBMPINFOHEADER /* size: 40 */
{
unsigned long biSize; // BITMAPINFOHEADER结构所需要的字数
unsigned long biWidth; // 图像宽度,单位为像素
unsigned long biHeight; // 图像高度,单位为像素,负数,则说明图像是正向的
unsigned short biPlanes; // 为目标设备说明位面数,其值将总是被设为1
unsigned short biBitCount; // 一个像素占用的bit位,值位1、4、8、16、24、32
unsigned long biCompression;// 压缩类型
unsigned long biSizeImage; // 位图数据的大小,以字节为单位
unsigned long biXPelsPerMeter;// 水平分辨率,单位 像素/米
unsigned long biYPelsPerMeter;// 垂直分辨率,单位 像素/米
unsigned long biClrUsed; //
unsigned long biClrImportant;//
} WINBMPINFOHEADER;
- 结构体字段详细说明:
- 位图文件举例
第0xe-0x11的4个字节(红色框):数值为0x28
,十进制为40
,表示位图信息头为40字节;
第0x12-0x15的4个字节和0x16-0x19的四个字节(橙色框):数值为0x64
,十进制为100
,表示宽高为100像素,与前面的位图属性宽度、高度对应;
第0x1a-0x1b的2个字节(紫色框):数值为1
;
第0x1c-0x1d的2个字节(紫色框):数值为4
,表示每个像素4bit,与前面的位图属性位深度对应;
第0x1e-0x21的4个字节(浅蓝色框):数值位0
,表示不压缩;
第0x22-0x25的4个字节(绿色框):数值为0x1452
,十进制为5202
,表示位图数据
的大小为5202字节,加上前面位图文件头
、位图信息头
、调色板
的118字节,刚好等于文件大小5320字节;
第0x26-0x29的4个字节和0x2a-0x2d的4个字节(蓝色框):数值0x0b12
,十进制数2834
;
第0x2e-0x31的4个字节和0x32-0x35的4个字节(灰色框):数值0
;
2.3 调色板
调色板
是为了让一些颜色深度比较小(1bit、4bit、8bit
)的位图可以表示颜色而设置的。调色板
存储颜色,后面的位图数据
存储颜色索引,这样调色板+位图数据
就可以表示颜色了。需要注意的是,16bit
、24bit
、32bit
的位图一般没有调色板,因为从16bit
开始就直接使用位图数据表示颜色了。
调色板可以理解为一个颜色数组,数组的每个元素就是一个4字节的argb值,数组大小由位图的颜色深度决定:1bit
位图的调色板有2个颜色(2x4=8字节)、4bit
位图的调色板有16个颜色(16x4=64字节)、8bit
位图的调色板有256个颜色(256x4=1024字节),整个调色板大小就是对应的颜色个数乘以4。
调色板数据大小 = 位图文件头的bfOffBits数值 - 位图文件头大小 - 位图信息头大小;
- 位图文件举例
上图红色框内的数据是4bit
位图的调色板,总共有16个颜色:0x00000000、0x00111111、0x00222222、0x00333333、0x00444444、0x00555555、0x00666666、0x00777777、0x00888888、0x00999999、0x00aaaaaa、0x00bbbbbb、0x00cccccc、0x00dddddd、0x00eeeeee、0x00ffffff
;数据大小等于0x76-54
个字节。下面看一下1bit
的位图数据:
上图红色框内的数据1bit
的调色板,总共有2个颜色:0x00ffffff、0x00000000
,数据大小等于0x3e-54
个字节。
2.4 位图数据
位图数据分两种情况,如果带调色板,则位图数据
存放的是调色板的颜色索引
,如果不带调色板,则位图数据
存放实际的argb值
。另外,由于Windows默认的扫描的最小单位是4字节,BMP图像顺应了这个要求,要求每行的数据的长度必须是4的倍数,如果不够需要进行比特填充,填充的值有可能是乱码。
4对齐的计算,以上面的位图文件举例:
①每个像素4bit,每行100个像素(宽为100),也就是每行400bit,等于50个字节,要求每行是4的倍数,所以每行需要补2个字节才是4的倍数,也就是每行52个字节;
②总共100行(高为100),所以位图数据就是52x100=5200字节;
③再加上前面三部分是118字节,总共是5318字节,由于5318不是4对齐的数,又要补2个字节使之4对齐,所以这个文件就是5320字节。
下图是4bit
带调色板位图数据,每4个bit
表示一个颜色索引,这里每4bit
的值都是f
,表示用调色板的第15个颜色来填充每个像素。另外,可以看到最下面一行有两个字节数值是0x22
,这就是4对齐补充的第51、52字节。
三、位图的其他知识
3.1 压缩的位图
压缩的位图是指位图数据
进行过压缩的位图,其压缩类型存储在位图信息头
的biCompression
字段,下面简单介绍一下是怎样压缩位图数据的。
BI_RGB
:不压缩
BI_REL8
:采用8比特游程编码
压缩位图数据
BI_REL4
:采用4比特游程编码
压缩位图数据