一 BMP文件格式
BMP(Bitmap)是Windows操作系统中的标准图像文件格式。
由于windows操作系统的发布时机远早于Linux、Android、IOS等操作系统,因此windows中很多数据格式和算法的标准也是当今所有操作系统必须要兼容的标准数据结构和算法。BMP是当前计算机中图像文件的标准文件格式,因此研究BMP文件格式的意义在于,它是计算机图像学这门课程的必修课。
BMP文件类型可以分成两类:设备相关位图(DDB)和设备无关位图(DIB)。
- BMP相较于其他图像格式的特点:
- BMP文件不采用任何压缩。BMP是原始的像素数据的集合,文件格式简单易懂。
- 图像的扫描方式是按从左到右、从下到上的顺序。
- 兼容1、2、4、8、16、32位颜色模式。
BMP文件从头到尾结构如下:
1. bmp文件头(BITMAPFILEHEADER结构)
typedef struct tagBITMAPFILEHEADER {
WORD bfType;
DWORD bfSize;
WORD bfReserved1;
WORD bfReserved2;
DWORD bfOffBits;
} BITMAPFILEHEADER, FAR*LPBITMAPFILEHEADER,*PBITMAPFILEHEADER;
bfType:’BM’两个可打印字符,用于标识BMP文件。
bfSize:文件大小
bfReserved1:保留,必须设置为0
bfReserved2:保留,必须设置为0
bfOffBits:从文件头到位图数据的偏移。一般来说,24位和32位的值是54(BITMAPINFOHEADER的大小+ BITMAPINFOHEADER的大小),而8位位图的值为1078(BITMAPINFOHEADER的大小+ BITMAPINFOHEADER的大小+颜色表的大小)
2 位图信息头(即BITMAPINFOHEADER结构)
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:信息头大小,即40字节
biWidth:以像素为单位图像的宽度
biHeight:以像素为单位图像的高度。如果为正,说明位图倒立(即数据表示从图像的左下角到右上角),如果为负说明正向
biPlanes:为目标设备说明颜色平面数,总被设置为1
biBitCount:bit/pixel,1、2、4、8、16、24、32
biCompression:图像的压缩类型,最常用的就是0(BI_RGB),表示不压缩
biSizeImages:4字节,说明位图数据的大小,当用BI_RGB格式时,可以设置为0
biXPelsPerMeter:表示水平分辨率,单位是像素/米,有符号整数
biYPelsPerMeter:表示垂直分辨率,单位是像素/米,有符号整数
biClrUsed:位图使用的调色板中的颜色索引数,为0说明使用所有
biClrImportant:对图像显示有重要影响的颜色索引数,为0说明都重要
另外需要注意的是,位图的每显示一行的扫描线长度总是4字节对齐的,计算方法是:
(width* biBitCount&31+ width* biBitCount)/4,不足的要补0,否则会导致文件格式解析错误。
3. 调色板(只存在于8位位图, 即RGBQUAD[256]数组)
typedef struct tagRGBQUAD {
BYTE rgbBlue;
BYTE rgbGreen;
BYTE rgbRed;
BYTE rgbReserved;
} RGBQUAD;
当位图是8bit时,像素值代表调色板的索引值。显示器很早就可以支持24位色,此模式主要用于减小文件大小和历史兼容。显示8位位图的像素值时,在调色板中按照索引值找到调色板中索引对应的红黄蓝三颜色的值,在显示器上显示对应的该24位颜色值。
4.位图数据
即像素值。24位像素值按照red,green,blue顺序排列。32位色按照ALPHA,red,green,blue顺序排列,alpha值代表透明度。16位比较特殊,一般是按照5:6:5的顺序表示red,green,blue这3种颜色的值。
二 BMP位图像素操作
1. 将24位位图转换为8位
创建并在调色板中构造合适的24位颜色值,然后将24位(或者32位)位图的颜色值修改为调色板中的索引值。为了简单,代码中将颜色值修改为依此递增的白色。因为纯白色的颜色值为0xffffff(红绿蓝三色的值必须相等,否则将会呈现三者之中值较大的那种颜色,而且三者的值越大,越加趋向于纯白色),所以调色板中的24位色是从010101,020202,030303,…,ffffff依次递增的256种、从灰色到纯白色的颜色值。
结果示例:
若是颜色表中不是这种排序,将会导致的结果如下(以绿色蓝色分量为0为例子):
2. 位图像素操作
使用代码实现区域像素的平移、在bmp图像中画白色矩形的操作。
因为一般的bmp文件是倒序存放的,即显示时的第一行位于位图数据文件的最后一行,最后一行位于位图文件的第一行中。为了操作和计算方便,需要将位图中扫描线翻转,操作之后,再将像素的扫描线翻转回去。具体实现看代码。
区域平移效果示例:
画矩形的效果示例:
平移并画矩形的效果示例:
工程代码如下:
https://download.csdn.net/download/m0_37567738/88571695
注意:代码编译时在“设置”->“c++”->“预处理器”->“预处理器定义”中添加” _CRT_SECURE_NO_WARNINGS”
三 参考链接
- c++将24位bmp转8位bmp灰度, 8位bmp灰度反色,24位转3张8位bmp灰度图
- bmp文件结构