BMP 图片的结构包括:文件信息、位图信息,调色板信息,位图数据。前面三个就是我们需自定义的头文件,如果不需要自定义头文件则只需包含windows.h文件即可。
需要注意的是,BMP文件头部信息的每一部分都是固定大小的,用sizeof计算windows.h自带BMP头文件结构体大小,可以得到它们的大小和都为54。
而vs默认进行4字节对齐,如果不取消4字节对齐,结构体的大小就会产生变化,导致bmp读图失败,所以在处理文件头部信息时需要按 1 字节对齐的方式访问,使用#pragma pack (1)取消字节对齐。
一、自定义头文件(header.h)
#pragma once
typedef unsigned short WORD;
typedef unsigned char BYTE;
#pragma pack (1) //按1字节进行对齐 即:不进行4字节对齐
struct BITMAPFILEHEADER //定义文件信息头,总大小14字节,如果4字节对齐了就是16字节,数据读取会出错
{
WORD bfType; //2字节,文件类型为BM
int bfSize; //4字节,位图文件大小
int bfReserved; //4字节保留字节
int bfOffbits; //4字节,字节偏移量
};
struct BITMAPINFOHEADER //定义位图信息段
{
int biSize; //4字节 此结构体长度为40
int biWidth; //4字节 位图宽
int biHeight; //4字节 位图高
WORD biPlanes; //2字节 平面数,为1
WORD biBitCount; //2字节 bmp颜色位数
int biCompression; //4字节 压缩方式,bmp图不压缩,为0
int biSizeImage; //4字节 实际位图数据占用的字节数无压缩,为0
int biXPelsPerMeter; //4字节 水平分辨率 bit/m
int biYPelsPerMeter; //4字节 垂直分辨率 bit/m
int biClrUsed; //4字节 使用的颜色数,bmp位数小于16才会用到
int biClrImportant; //4字节 重要颜色数,如果为0则所有颜色都重要
};
struct RGBQUAD //定义调色板
{
BYTE rgbRed;
BYTE rgbGreen;
BYTE rgbBlue;
BYTE rgbReserved; //保留位,为0
};
二、定义bmp结构体接口文件
1.使用了ifdef预处理器区分window.h自带的接口文件和自己定义的文件
#define HEADER
#ifdef HEADER
#include "header.h" //自定义接口文件
#else
#include<windows.h>
#endif
2.BMP结构体
struct BMP
{
BITMAPFILEHEADER header; // 定义文件头信息
BITMAPINFOHEADER info; // 定义位图信息头
RGBQUAD rgb[256]; // 定义调色盘,只有1、4、8位图才需要调色盘
unsigned char * data = nullptr; // 定义位图数据指针
~BMP()
{
if (data != nullptr)
{
delete[] data;
data = nullptr;
}
}
};