BMP 图片也就是位图(bitmap),直接存储像素数据,几乎不进行压缩,图像信息丰富,比较明显的缺点就是占用空间大。
BMP 图片的结构很简单,首先是文件信息、接着是位图信息,然后是调色板信息,最后是位图数据。需要注意的是,文件头部信息的每一部分都是固定大小的,所以在处理文件头部信息时需要按 1 字节对齐的方式访问,或者在声明结构体时用关键字 “__attribute__((packed))
” 取消字节对齐。
1. 文件信息
文件信息结构体:
typedef struct tag_bitmap_file_header{
unsigned short file_type;
unsigned int file_size;
unsigned short reserved1;
unsigned short reserved2;
unsigned int offset_bits;
} __attribute__((packed)) bitmap_file_header;
这个结构体的大小固定为 14 个字节。
file_type:文件标识,BMP 文件值固定为 0x4D42,存储为小端模式,转换成 ASCII 就是 “BM”。
file_size:整个文件的大小。
reserved1:保留。
reserved2:保留。
offset_bits:位图数据在文件中的偏移值,等于 “文件信息+位图信息+调色板信息”。
2. 位图信息
位图信息结构体:
typedef struct tag_bitmap_info_header {
unsigned int bitmap_info_size;
int bitmap_width;
int bitmap_height;
unsigned short planes;
unsigned short image_depth;
unsigned int compression;
unsigned int image_size;
int x_pels_permeter;
int y_pels_permeter;
unsigned int color_used;
unsigned int color_important;
} __attribute__((packed)) bitmap_info_header;
这个机构体的大小固定为 40 个字节。
bitmap_info_size:位图信息的大小,固定为 40。
bitmap_width:位图宽度。
bitmap_height:位图高度,影响位图数据的存储方式。值为正数时,从位图数据的最后一行开始保存,也就是文件位图数据的第一行是图片数据的最后一行,这种存储方式支持压缩。值为负数时,文件位图数据的第一行就是图片数据的第一行。
planes:位图的位面数,固定为 1。
image_depth:位图的图像深度,表示位图数据中,几个二进制位表示一个像素点,如 8 bits 表示,8 个二进制位表示一个像素点。
compression:位图压缩方式。值为 BI_RGB 表示无压缩(没研究过压缩的)。
image_size:位图的数据大小。
x_pels_permeter:指定位图目标设备的水平打印分辨率,表示水平方向每米的像素点数量,可以是 0。
y_pels_permeter:指定位图目标设备的垂直打印分辨率,表示垂直方向每米的像素点数量,可以是 0。
color_used::位图实际使用调色板的颜色数量,图像深度少于或等于 8 bits 时,值有效。值为 0 表示使用了整个调色板的颜色。
color_important:重要的颜色数量,值通常等于 color_used,值为 0 时表示所有颜色都重要。
3. 调色板信息
调色板信息结构体:
typedef struct tag_bitmap_palette {
unsigned char blue;
unsigned char green;
unsigned char red;
unsigned char reserved;
} __attribute__((packed)) bitmap_palette;
这个机构体的大小固定为 4 个字节。
blue:蓝色。
green:绿色。
red:红色。
reserved:保留。
调色板数据是可选的,但是如果位图的图像深度少于或等于 8 bits 时,文件头部信息必须要带有调色板数据。
4. 位图数据
位图数据处理的时候注意图像深度和位图数据的存储方式。