BITMAPFILEHEADER、BITMAPINFOHEADER及BMP结构详解

BMP文件:

  是Windows操作系统所推荐和支持的图像文件格式,是一种将内存或显示器的图像数据不经过压缩而直接按位存盘的文件格式,所以称为位图(bitmap)文件

BMP文件总体上由4部分组成

 位图文件头(bitmap-file header)14bytes

 位图信息头(bitmap-information header)40bytes

 彩色表/调色板(color table)

 位图数据(bitmap-data)

1.位图文件头(bitmap-file header)

位图文件头(bitmap-file header)包含了图像类型、图像大小、图像数据存放地址和两个保留未使用的字段

打开WINGDI.h文件,搜索"BITMAPFILEHEADER"就可以定位到BMP文件的位图文件头的数据结构定义

typedef struct tagBITMAPFILEHEADER { 
WORD    bfType; 
DWORD   bfSize; 
WORD    bfReserved1; 
WORD    bfReserved2; 
DWORD   bfOffBits; 
} BITMAPFILEHEADER, FAR *LPBITMAPFILEHEADER, *PBITMAPFILEHEADER;

字 段 名      大小(单位:字节)      描 述

bfType                                 2                                    位图类别,根据不同的操作系统而不同,在Windows中,此字段的值总为‘BM’

bfSize           4           BMP图像文件的大小,包括这14个字节

bfReserved1                         2                                    总为0

bfReserved2                         2                                    总为0

bfOffBits                              4                                    从文件头到实际的位图数据的偏移字节数

bfOffBits 从文件头开始到颜色数据的偏移量  54+sizeof(RGBQUAD)*256
bfSize  图片的大小,bfOffBits + 长 X 宽 X 位数  例如对于128X128X24位的图像  bfSize=128X128X24 + 54+sizeof(RGBQUAD)*256

2.位图信息头(bitmap-information header)

位图信息头(bitmap-information header)包含了位图信息头的大小、图像的宽高、图像的色深、压缩说明图像数据的大小和其他一些参数

打开WINGDI.h文件,搜索"tagBITMAPINFOHEADER"就可以定位到BMP文件的位图信息头的数据结构定义

typedef struct tagBITMAPINFOHEADER{ 
DWORD      biSize; 
LONG        biWidth; 
LONG        biHeight; 
WORD       biPlanes; 
WORD       biBitCount; 
DWORD      biCompression; 
DWORD      biSizeImage; 
LONG        biXPelsPerMeter; 
LONG        biYPelsPerMeter; 
DWORD      biClrUsed; 
DWORD      biClrImportant; 
} BITMAPINFOHEADER, FAR *LPBITMAPINFOHEADER, *PBITMAPINFOHEADER;

字 段 名      大小(单位:字节)      描 述

biSize           4                                    本结构的大小,根据不同的操作系统而不同,在Windows中,此字段的值总为28h字节=40字节

biWidth           4           位图的宽度,单位是像素

biHeight          2                                    位图的高度,单位是像素

biPlanes         2                                    固定值1

biBitCount         2                                    每个像素的位数(1-黑白图,4-16色,8-256色,24-真彩色)

biCompression       4              压缩方式,BI_RGB(0)为不压缩

biSizeImage                        4                                     实际的位图数据占用的字节数,BI_RGB时可设为0

biXPelsPerMeter      4                                      水平分辨率,单位像素/m

biYPelsPerMeter                 4                                      垂直分辨率,单位像素/m

biClrUsed         4             指定本图象实际用到的颜色数,如果该值为零,则用到的颜色数为2biBitCount

biClrImportant        4                                      重要的颜色数,此值为0时所有颜色都重要,对于使用调色板的BMP图像来说,当显卡不能够显示所有颜色时,此值将辅助驱动程序显示颜色

3.彩色表/调色板(color table)

彩色表/调色板(color table)是单色、16色和256色图像文件所特有的,相对应的调色板大小是2、16和256,调色板以4字节为单位,每4个字节存放一个颜色值,图像 的数据是指向调色板的索引

可以将调色板想象成一个数组,每个数组元素的大小为4字节,假设有一256色的BMP图像的调色板数据为:

调色板[0]=黑、调色板[1]=白、调色板[2]=红、调色板[3]=蓝…调色板[255]=黄

图像数据01 00 02 FF表示调用调色板[1]、调色板[0]、调色板[2]和调色板[255]中的数据来显示图像颜色

在早期的计算机中,显卡相对比较落后,不一定能保证显示所有颜色,所以在调色板中的颜色数据应尽可能将图像中主要的颜色按顺序排列在前面,位图信息 头的biClrImportant字段指出了有多少种颜色是重要的

每个调色板的大小为4字节,按蓝、绿、红存储一个颜色值

打开WINGDI.h文件,搜索"tagRGBTRIPLE"就可以定位到BMP文件的调色板的数据结构定义

typedef struct tagRGBQUAD { 
BYTE    rgbBlue; 
BYTE    rgbGreen; 
BYTE    rgbRed; 
BYTE    rgbReserved; 
} RGBQUAD;

字 段 名      大小(单位:字节)      描 述

rgbBlue           1                                    蓝色的亮度(值范围为0-255)

rgbGreen         1           绿色的亮度(值范围为0-255)

rgbRed          1                                    红色的亮度(值范围为0-255)

rgbReserved          2                                   保留,总为0

说明:

调色板实际上是一个数组,共有biClrUsed个元素(如果该值为零,则有2biBitCount个元素)

颜色表中RGBQUAD结构数据的个数有biBitCount来确定:
当biBitCount=1,4,8时,分别有2,16,256个表项
当biBitCount=24时,没有颜色表项
 
1:单色图,调色板中含有两种颜色,也就是我们通常说的黑白图片
4:16色图
8:256色图,通常说的灰度图
16:64K图,一般没有调色板,图像数据中每两个字节表示一个像素,5个或6个位表示一个RGB分量
24:16M真彩色图,一般没有调色板,图像数据中每3个字节表示一个像素,每个字节表示一个RGB分量
32:4G真彩色,一般没有调色板,每4个字节表示一个像素,相对24位真彩图而言,加入了一个透明度,即RGBA模式

4.位图数据(bitmap-data)

对于用到调色板的位图,图象数据就是该象素颜在调色板中的索引值。对于真彩色图,图象数据就是实际的R、G、B值

位图数据记录了位图的每一个像素值,记录顺序是在扫描行内是从左到右,扫描行之间是从下到上。位图的一个像素值所占的字节数:
当biBitCount=1时,8个像素占1个字节;
当biBitCount=4时,2个像素占1个字节;
当biBitCount=8时,1个像素占1个字节;
当biBitCount=24时,1个像素占3个字节,按顺序分别为B,G,R
 

对于2色位图,用1位就可以表示该象素的颜色(一般0表示黑,1表示白),所以一个字节可以表示8个象素。

对于16色位图,用4位可以表示一个象素的颜色,所以一个字节可以表示2个象素。(要显示16个颜色  2的4次方)因此4位就能表示一个像素

对于256色位图,一个字节刚好可以表示1个象素。

对于真彩色图,三个字节才能表示1个象素,哇,好费空间呀!没办法,谁叫你想让图的颜色显得更亮丽呢,有得必有失嘛

 

如果图像是单色、16色和256色,则紧跟着调色板的是位图数据,位图数据是指向调色板的索引序号。

如果位图是16位、24位和32位色,则图像文件中不保留调色板,即不存在调色板,图像的颜色直接在位图数据中给出。

16位图像使用2字节保存颜色值,常见有两种格式:5位红5位绿5位蓝和5位红6位绿5位蓝,即555格式和565格式。555格式只使用了15 位,最后一位保留,设为0。

24位图像使用3字节保存颜色值,每一个字节代表一种颜色,按红、绿、蓝排列。

32位图像使用4字节保存颜色值,每一个字节代表一种颜色,除了原来的红、绿、蓝,还有Alpha通道,即透明色。

如果图像带有调色板,则位图数据可以根据需要选择压缩与不压缩,如果选择压缩,则根据BMP图像是16色或256色,采用RLE4或RLE8压缩算 法压缩

 补充:

(1)位图全部的像素,是按照自下向上,自左向右的顺序排列的

RGB数据也是倒着念的,原始数据是按B、G、R的顺序排列的

(2)因为32位的Windows操作系统处理4个字节(32位)的速度比较快,所以BMP的每一行颜色占用的字节数规定为4的整数倍。MyBmp.bmp中一行颜色有两个像素,共占用6字节,如果要补齐4*2=8字节,就要再加两个0字节

行补位的公式为:widthBytes = (width*biBitCount+31)/32*4

参数说明:Width:位图的实际宽度

     biBitCount:每个像素的位数

     1-黑白图,4-16色,8-256色,24-真彩色

位图信息头和颜色表组成位图信息,BITMAPINFO结构定义如下:
typedef struct tagBITMAPINFO{
BITMAPINFOHEADER bmiHeader;//位图信息头
RGBQUAD bmiColors[1];//颜色表
}__attribute__((packed)) BITMAPINFO;

参考链接:https://www.cnblogs.com/lzlsky/archive/2012/08/16/2641698.html

     https://baike.baidu.com/item/BMP/35116

     https://blog.csdn.net/av_geek/article/details/18814073

原文地址:https://www.cnblogs.com/IAMSailorMoon/p/10567760.html