BMP文件详解(参考《Direct实务精选》 陆其明著)

来源:互联网 发布:傣族语言翻译软件 编辑:程序博客网 时间:2024/06/05 13:06
        计算机上使用的静态图片文件有很多种格式,常见的有BMP、GIF、JPEG、PNG、PCX、TIFF等。其中,BMP(Bitmap的缩写)是一种比较简单的、在Windows上也用得最多的文件格式。
BMP文件可以用每像素1、4、8、16、24或32位来编码颜色信息,这个位数称为图像的颜色深度,它决定了图像所含的最大颜色数,如一幅1-bpp(bit per pixel,每个像素使用的位数)的图像只能有两种颜色,而一幅24-bpp的图像可以有16777216(即224)种不同的颜色。颜色的数量越多,所表现的图像内容就越生动、越逼真。
一个典型的BMP文件包含4个主要的部分:BMP文件头、BMP信息头、调色板和位图数据。如图2.17所示,一个100 x 56大小的位图,如果保存为16色的BMP文件,则它的文件数据如图2.18所示,如果保存为24位的BMP文件,则它的文件数据如图2.19所示。(注意:16、24、32位的位图均不使用调色板。)



1. BMP 文件头
BMP文件头使用一个数据结构BITMAPFILEHEADER来表示,它包含了BMP文件的类型、文件大小和位图数据的起始位置等信息。
typedef struct tagBITMAPFILEHEADER
{
WORD bfType; // BMP文件的类型,必须为字符“BM”
DWORD bfSize; // BMP文件的大小,以字节为单位
WORD bfReserved1; // BMP文件保留字,必须为0
WORD bfReserved2; // BMP文件保留字,必须为0
DWORD bfOffBits; // 位图数据起始位置(相对于文件开头),以字节为单位

} BITMAPFILEHEADER;


2. BMP 信息头
BMP信息头使用一个数据结构BITMAPINFOHEADER来表示,它说明了位图的尺寸、颜色深度等信息。
typedef struct tagBITMAPINFOHEADER
{
DWORD biSize; // 本结构所占用的字节数
LONG biWidth; // 图像的宽度,以像素为单位
LONG biHeight; // 图像的高度,以像素为单位
WORD biPlanes; // 目标设备的平面数,必须为1
WORD biBitCount; // 表示每个像素所需的位数
DWORD biCompression; // 图像的压缩类型
DWORD biSizeImage; // 图像的大小,以字节为单位
LONG biXPelsPerMeter; // 图像水平分辨率,每米像素数
LONG biYPelsPerMeter; // 图像垂直分辨率,每米像素数
DWORD biClrUsed; // 位图实际使用的调色板中的颜色数
DWORD biClrImportant; // 位图显示过程中重要的颜色数
} BITMAPINFOHEADER;
BITMAPINFOHEADER结构中一些重要成员的说明如下:
(1)biSize
本数据结构的大小为:
biSize = sizeof(BITMAPINFOHEADER);
(2)biWidth
图像的宽度,以像素为单位。如果位图数据是压缩的,则指定解压后的图像宽度。
(3)biHeight
图像的高度,以像素为单位。如果位图数据是压缩的,则指定解压后的图像高度。如果biHeight的值是正的,说明位图数据是从下往上(Bottom-up)扫描的,即位图数据中的第一个像素对应图像最后一行左边的第一个像素,然后依次往右第二个像素、第三个像素...然后是图像的倒数第二行...直到图像的第一行。如果biHeight的值是负的,说明位图数据是从上往下(Top-down)扫描的,即位图数据依次对应图像的第一行、第二行...直到最后一行。图像的两种扫描方式如图2.20所示。


(4)biBitCount
表示每个像素所需的位数,必须是0(可能是压缩数据)、1(2色)、4(16色)、8(256色)、16(最多216种颜色)、24(224种颜色)、32(最多224种颜色,多出来的8位用作Alpha通道值或者不用)。其中,1、4、8位的都需要调色板;16位时,如果biCompression成员的值为BI_RGB,则是RGB555的格式,如果biCompression成员的值为BI_BITFIELDS,则BITMAPINFOHEADER结构后面必须跟着用于提取RGB各分量的屏蔽字(3个DWORD类型的常量),图像的具体格式可能是RGB555,也可能是RGB565;24位时,每个像素使用3个字节表示,注意字节顺序是BGR;32位时,每个像素使用4个字节表示,注意字节顺序是BGRA,其中A是不用的字节或表示Alpha通道值。
(5)biSizeImage
图像的大小,以字节为单位,一般情况下它的计算公式为biSizeImage = biWidth x biHeight x biBitCount / 8。当图像的宽度字节数不是4的整数倍时,应以4为边界对齐,比如一幅16-bpp、宽高为11 x 11的位图,它的有效图像宽为11 x 16 / 8 = 22字节,而实际存储时应该对齐为24字节(多出的2个字节填充,显示时可以忽略),如图2.21所示。相应地,存储整幅图像需要的空间应该为24 x 11 = 264字节,而不是22 x 11 = 242字节。因此,图像大小的正确计算方法应为:
long stride = (biWidth x biBitCount + 31) / 8;

biSizeImage = stride x biHeight;

(6)biCompression
位图的压缩格式可以是BI_RGB、BI_RLE8、BI_RLE4、BI_BITFIELDS、BI_JPEG、BI_PNG等。注意:如果位图数据是一种压缩格式,则这个位图一定是从下往上扫描的(从上往下扫描的位图不作压缩)。

3. 调色板
调色板用于说明位图中使用的颜色,它有若干个表项,每一个表项都用一个RGBQUAD数据结构(占用4个字节)定义一种颜色。RGBQUAD结构的定义如下:
typedef struct tagRGBQUAD {
BYTE rgbBlue; // 蓝色分量(取值范围为0~255)
BYTE rgbGreen; // 绿色分量(取值范围为0~255)
BYTE rgbRed; // 红色分量(取值范围为0~255)
BYTE rgbReserved; // 保留
} RGBQUAD;
调色板中RGBQUAD结构的个数由biBitCount的值来确定:当biBitCount等于1、4、8时,分别有2、16、256个表项;当biBitCount等于16、24、32时,表项个数为0(也就是说不使用调色板)。BMP信息头和调色板组成位图信息——另一个数据结构BTMAPINFO,定义如下:
typedef struct tagBITMAPINFO {
BITMAPINFOHEADER bmiHeader; // BMP信息头
RGBQUAD bmiColors[1]; // 调色板颜色数组

} BITMAPINFO;


4. 位图数据

位图数据记录了位图的每一个像素值,记录顺序为:在扫描行内从左到右,而在扫描行之间从下往上(biHeight值为正数)或从上往下(biHeight值为负数)。位图的一个像素值所占的字节数由biBitCount的值确定。值得注意的是,当biBitCount等于1、4、8时,位图数据中的各像素值表示的不是真正的颜色值,而是颜色值在调色板中对应的索引值;当biBitCount等于16、24、32时,位图数据中的各像素值才直接表示这个像素的RGB分量值。


//END ICTwangbiao

原创粉丝点击