BMP格式图像简述
BMP格式的图像是最基本的一种图像。
BMP 文件组成:由文件头,位图信息头,颜色信息(即调色板信息)和图形数据四部分组成.
文件头 主要包含 文件的大小,文件类型,图像数据偏离文件头的长度等信息;
位图信息头 包含图象的尺寸信 息,图像用几个比特数值来表示一个像素,图像是否压缩,图像所用的颜色数等信息.
调色板信息 包含图像所用到的颜色表, 显示图像时需用到这个颜色表来生成调色板
数据块 表示图像的相应的像素值 位图数据记录了位图的每一个像素值(真彩色图像)或该对应像素的颜色表的索引值(其他图像)。
压缩与否:对于 BMP 文件格式,在处理单色图像和真彩色图像的时候,无论图象数据多么 庞大,都不对图象数据进行任何压缩处理,一般情况下,如果位图采用压缩格式,那么 16 色图像采用 RLE4 压缩算法,256 色图像采用 RLE8 压缩算法.
颜色表示:RGBQUAD 结构中定义的颜色值中,红色,绿色和蓝色的排列顺序与一般真彩色图像文件的颜色数据排列顺序恰好相反, 既: 若某个位图中的一个像素点的颜色的描述为"00,00,ff,00",则表示该点为红色,而不是蓝色.
像素值的大小:位图的一个像素值所占的字节数:
当 biBitCount=1 时,8 个像素占 1 个字节;
当 biBitCount=4 时,2 个像素占 1 个字节;
当 biBitCount=8 时,1 个像素占 1 个 字节;
当 biBitCount=24 时,1 个像素占 3 个字节,此时图像为真彩色图像.
当图像不是为真 彩色时,图像文件中包含颜色表,位图的数据表示对应像素点在颜色表中相应的索引值,
当为真彩色时, 每一个像素用三个字节表示图像相应像素点彩色值,每个字节分别对应 R, G, B 分量的值,这时候图像文件中没有颜色表.
一行所占的字节数: DataSizePerLine= (biWidth* biBitCount+31)/8;// 一个扫描行所占的字节数
或 DataSizePerLine=(biWidth* biBitCount/8+3)/4*4;
位图数据大小(不压缩情况下): DataSize= DataSizePerLine* biHeight.
四个结构体:BITMAPFILEHEADER 以及 BITMAPINFOHEADER + RGBQUAD = BITMAPINFO
typedef struct tagBITMAPFILEHEADER {
WORD bfType; // 位图文件的类型,必须为"BM" 即0x4d42
DWORD bfSize; // 位图文件的大小,以字节为单位
WORD bfReserved1; // 位图文件保留字,必须为 0
WORD bfReserved2; // 位图文件保留字,必须为 0
DWORD bfOffBits; // 位图数据的起始位置,以相对于位图文件头的偏移量表示,以字节为 单位
} BITMAPFILEHEADER;该结构占据 14 个字节.
typedef struct tagBITMAPINFOHEADER{
DWORD biSize; // 本结构所占用字节数
LONG biWidth; // 位图的宽度,以像素为单位
LONG biHeight; // 位图的高度,以像素为单位
WORD biPlanes; // 目标设备的平面数,必须为 1
WORD biBitCount// 每个像素所需的位数, 必须是 1(双色), 4(16 色), 8(256 色)或 24(真彩色) 之一
DWORD biCompression; // 位图压缩类型,必须是 0(不压缩),1(BI_RLE8 压缩类型)或 2(BI_RLE4 压缩类型)之一
DWORD biSizeImage; // 压缩位图的大小,以字节为单位 非压缩图像为0
LONG biXPelsPerMeter; // 位图水平分辨率,每米像素数
LONG biYPelsPerMeter; // 位图垂直分辨率,每米像素数
DWORD biClrUsed;// 位图实际使用的颜色表中的颜色数
DWORD biClrImportant;// 位图显示过程中重要的颜色数 0表示都重要
} BITMAPINFOHEADER;该结构占据 40 个字节.
调色板中每一个颜色用一个RGBQUAD结构来表示:
typedef struct tagRGBQUAD {
BYTErgbBlue;// 蓝色的亮度(值范围为 0-255)
BYTErgbGreen; // 绿色的亮度(值范围为 0-255)
BYTErgbRed; // 红色的亮度(值范围为 0-255)
BYTErgbReserved;// 保留,必须为 0
} RGBQUAD;
颜色表中 RGBQUAD 结构数据的个数由 BITMAPINFOHEADER 中的 biBitCount 项来 确定,
当 biBitCount=1,4,8 时,分别有 2,16,256 个颜色表项,当 biBitCount=24 时,图像为真彩色,图像中每个像素的颜色用三个字节表示,分别对应 R,G,B 值,图像文件没有颜色表项
位图信息头和颜色表组成位图信息BITMAPINFO
对于256色BMP图像,其颜色表项的各个RGB分量是相等的,从0-255,颜色表项有256个。
typedef struct tagBITMAPINFO {
BITMAPINFOHEADER bmiHeader; // 位图信息头
RGBQUAD bmiColors[1]; // 颜色表
} BITMAPINFO;
与调色板相关的两个结构:
逻辑调色板结构 LOGPALETTE
typedef struct tagLOGPALETTE {
WORD palVersion;//调色板的板本号,应该指定该值为 0x300;
WORD palNumEntries;//调色板中的表项数,对于灰度图像该值为 256;
PALETEENTRY palPalEntry[1];//调色板中的颜色表项,由于该表项的数目不一定,所以这里 数组长度定义为 1,灰度图像对应的该数组的长度为 256;
}LOGPALETTE;
颜色表项结构 PALETTEENTRY :定义了调色板中的每一个颜色表项的颜色和使用方式
typedef struct tagPALETTEENTRY {
BYTE peRed; //R 分量值;
BYTE peGreen; //G 分量值;
BYTE peBlue; //B 分量值;
BYTE peFlags; // 该颜色被使用的方式,一般情况下设为"0";
}PALETTEENTRY;
调色板操作简述:
Windows 系统使用调色板管理器来管理与调色板有关的操作, 通常活动窗口的调色板即 是当前系统调色板, 所有的非活动窗口都必须按照此系统调色板来显示自己的颜色, 此时调 色板管理器将自动的用系统调色板中的最近似颜色来映射相应的显示颜色.
如果窗口或应用 程序按自己的调色板显示颜色, 就必须将自己的调色板载入到系统调色板中, 这种操作叫作 实现调色板,
实现调色板包括两个步骤,既首先将调色板选择到设备上下文中,然后在设备 上下文中实现它.
可以通过 CDC: :SelectPalette(),CDC: :RealizePalette()或相应的 API 函 数来实现上述的两个步骤.
调色板改变时的消息响应机制:
在实现调色板的过程中,通过在主框架类中处理 Windows 定义 的消息 WM_QUERYNEWPALETTE ,WM_PALETTECHANGED 及视图类中处理自定义消 息 WM_DOREALIZE ( 该 消 息 在 主 框 架 窗 口 定 义 如 下 : #define WM_REALIZEPAL (WM_USER+101))来实现调色板的操作.
当系统需要处理调色板的变化时,将向程序的主 窗口发送 WM_QUERYNEWPALETTE ,WM_PALETTECHANGED,例如当某一窗口即将 激活时,主框架窗口将收到 WM_QUERYNEWPALETTE 消息,通知该窗口将要收到输入焦 点,给它一次机会实现其自身的逻辑调色板;
当系统调色板改变后,主框架窗口将收到 WM_PALETTECHANGED 消息,通知其它窗口系统调色板已经改变,此时每一窗口都应该 实现其逻辑调色板,重画客户区.
由于上述的调色板变更消息是发往主框架窗口的, 所以我们只能在主窗口中响应这两个 消息,然后由主框架窗口通知各个视窗,使得程序激活时能自动装载自己的调色板.
我们定 义的用户消息 WM_REALIZEPAL 用于主框架窗口通知视窗它已经收到调色板变更消息, 视 窗应该协调其调色板.