1.1 位图文件头
位图文件头主要用于识别位图文件。以下是位图文件头结构的定义: typedef struct tagBITMAPFILEHEADER {
WORD bfType;
DWORD bfSize;
WORD bfReserved1;
WORD bfReserved2;
DWORD bfOffBits;
} BITMAPFILEHEADER;
其中的bfType值应该是“BM”(0x4d42),标志该文件是位图文件。bfSize的值是位图文件的大小。
1.2 位图信息结构
位图信息结构中所记录的值用于分配内存,设置调色板信息,读取像素值等。以下是位图信息结构的定义:
typedef struct tagBITMAPINFO {
BITMAPINFOHEADER bmiHeader; //信息头
RGBQUAD bmiColors[1]; //颜色表
} BITMAPINFO;
可见位图信息也是由两部分组成的:位图信息头 + 颜色表
2
1.2.1 位图信息头
位图信息头包含了单个像素所用字节数以及描述颜色的格式,此外还包括位图的宽度、高度、目标设备的位平面数、图像的压缩格式。以下是位图信息头结构的定义:
typedef struct tagBITMAPINFOHEADER{
DWORD biSize; //结构BITMAPINFOHEADER的字节数,即
//sizeof(BITMAPINFOHEADER)*
LONG biWidth; //以像素为单位的图像宽度*
LONG biHeight; //以像素为单位的图像长度
WORD biPlanes; //目标设备的位平面数
WORD biBitCount //每个像素的位数*(1)
DWORD biCompression; //图像的压缩格式(这个值几乎总是为0) DWORD biSizeImage; //以字节为单位的图像数据的大小(对//BI_RGB压缩方式而言)
LONG biXPelsPerMeter; //水平方向上的每米的像素个数
LONG biYPelsPerMeter; //垂直方向上的每米的像素个数
DWORD biClrUsed; //调色板中实际使用的颜色数(2) DWORD biClrImportant; //现实位图时必须的颜色数(3)
} BITMAPINFOHEADER;
说明:
(1)、*是需要加以注意的部分,因为它们是我们在进行位图操作时经常参考的变量。
(2)、biBitCount:对于每个像素的字节数,分别有以下意义:
0,用在JPEG格式中
1,单色图,调色板中含有两种颜色,也就是我们通常说的黑白图片 4,16色图
8,256色图,通常说的灰度图
16,64K图,一般没有调色板,图像数据中每两个字节表示一个像素,5个或6个位表示一个RGB分量
3
24,16M真彩色图,一般没有调色板,图像数据中每3个字节表示一个像素,每个字节表示一个RGB分量
32,4G真彩色,一般没有调色板,每4个字节表示一个像素,相对24位真彩图而言,加入了一个透明度,即RGBA模式
(3)、biClrUsed:这个值通常为0,表示使用biBitCount确定的全部颜色,例外是使用的颜色数目小于制定的颜色深度的颜色数目的最大值。
(4)、biClrImportant:这个值通常为0,表示所有的颜色都是必需的。
1.2.2 颜色表
颜色表一般是针对16位以下的图像而设置的,对于16位和16位以上的图像,由于其位图像素数据中直接对对应像素的RGB(A)颜色进行描述,因而省却了调色板。而对于16位以下的图像,由于其位图像素数据中记录的只是调色板索引值,因而需要根据这个索引到调色板去取得相应的RGB(A)颜色。颜色表的作用就是创建调色板。
图1.2是带调色板和不带调色板的位图的简单示意图:
a. 带调色板的位图 b. 不带调色板的位图
图1.2 不同的位图结构
颜色表是由颜色表项组成的,颜色表项结构的定义如下:
typedef struct tagRGBQUAD {
BYTE rgbBlue;
BYTE rgbGreen;
4
BYTE rgbRed;
BYTE rgbReserved;
} RGBQUAD;
其中需要注意的问题是,RGBQUAD结构中的颜色顺序是BGR,而不是平常的RGB。
1.2.3位图数据
最后,在位图文件头、位图信息头、位图颜色表之后,便是位图的主体部分:位图数据。位图数据记录了位图的每一个像素值,记录顺序是在扫描行内是从左到右,扫描行之间是从下到上。位图的一个像素值所占的字节数:
当biBitCount=1时,8个像素占1个字节;
当biBitCount=4时,2个像素占1个字节;
当biBitCount=8时,1个像素占1个字节;
当biBitCount=16时,1个像素占2个字节(RGB555格式);
当biBitCount=24时,1个像素占3个字节(BGR格式);
当biBitCount=32时,1个像素占4个字节(BGR-格式,-表示不处理的字节)
注意:
Windows规定一个扫描行所占的字节数必须是4的倍数(即以long为单位),不足的以0填充,一个扫描行所占的字节数计算方法:
DataSizePerLine= (biWidth* biBitCount+31)/8; // 一个扫描行所占的字节数
每行的字节数必须是4的倍数。DataSizePerLine==
DataSizePerLine/4*4;
位图数据的大小(不压缩情况下):
DataSize= DataSizePerLine* biHeight;
2、CDIB类
该类将位图文件的读取、象素数据的获取及显示进行了封装。具体的代码见附带的电子参考资料。下面介绍具体的成员和方法:
5