http://blog.chinaunix.net/u/11557/showart.php?id=86169(出处)位图是最常用的windows图形格式,通过windows API函数可以直接读取并绘制,不过,有时我们还是需要自己控制,那么,就让我们看看他的格式吧!位图文件结构表位图文件位图文件头14 字节位图信息头40 字节彩色表(调色板)4N 字节位图数据x 字节 构件详解:
位图文件头 位图文件头包含文件类型、文件大小、存放位置等信息。结构定义如下: typedef struct tagBITMAPFILEHEADER { UNIT bfType; DWORD bfSize; UINT bfReserved1; UINT bfReserved2; DWORD bfOffBits; }BITMAPFILEHEADER; 其中:bfType 说明文件类型,在windows系统中为BM。bfSize 说明文件大小。bfReserved1 bfReserved2 保留,设置为0。bfOffBits 说明实际图形数据的偏移量。 位图信息头 位图信息头包含位图的大小、压缩类型、和颜色格式,结构定义如下: typedef struct tagBITMAPINFOHEADER { DWORD biSize; LONG biWidth; LONG biHeight; WORD biPlanes; WORD biBitCount; DWORD biCompression; DWORD biSizeImage; LONG biXPelsPerMerer; LONG biYPelsPerMerer; DWORD biClrUsed; DWORD biClrImportant; }BITMAPINFOHEADER; 其中: biSize 说明BITMAPINFOHEADER结构所需字节数,在windows系统中为28hbiWidth 说明图像宽度biHeight 说明图像高度biPlanes 为目标设备说明位面数,其值设为1biBitCount每个像素的位数,单色位图为1,256色为8,24bit为24。biCompression压缩说明,BI_RGB:无压缩,BI_RLE8:8位RLE压缩,BI_RLE4:4位RLE压缩biSizeImage说明图像大小,如无压缩,可设为0biXPelsPerMeter水平分辨率biYPelsPerMeter垂直分辨率biClrUsed 位图使用的颜色数biImportant重要颜色数目 彩色表 彩色表包含的元素与位图所具有的颜色数目相同,像素颜色用结构RGBQUAD来表示:typedef struct tagRGBQUAD{ BYTE rgbBlue; BYTE rgbGreen; BYTE rgbRed; BYTE rgbReserved;}RGBQUAD;其中:rgbBlue 指定蓝色强度rgbGreen 指定绿色强度rgbRed 指定红色强度rgbReserved保留,设为0 位图数据 紧跟在彩色表后的是图像数据震裂,图像每一扫描行有连续的字节组成,扫描行由底向上存储,阵列中第一字节为左下角像素,最后一字节为右上角像素。 要想处理图像文件就必须知道这些图像文件的构成方式。在常用的图像格式中,以24位真彩色的BMP位图格式比较常用,而且构成比较简单,所以我们就以它作为讲解的对象。首先我们找一幅 24 位真彩色的位图用 16 进制编辑器将其打开,查看方式切换到以 HEX 方式查看的话,你们就可以看到类似下面这样的数据了。这其实就是 BMP 文件中的图像数据。这些数据就代表着我们平常看到的图像。00000 42 4D 96 61 02 00 00 00 00 00 36 00 00 00 28 00 00010 00 00 04 01 00 00 C8 00 00 00 01 00 18 00 00 00 00020 00 00 60 61 02 00 00 00 00 00 00 00 00 00 00 00 00030 00 00 00 00 00 00 0A 0A 0A 0B 0B 0B 10 10 10 17 00040 17 17 1C 1C 1C 1B 1B 1B 14 14 14 0D 0D 0D 0F 0F 00050 0F 0E 0E 0E 0E 0E 0E 0E 0E 0E 10 10 10 13 13 13 00060 16 16 16 18 18 18 15 15 15 19 19 19 17 17 17 0F 00070 0F 0F 0B 0B 0B 0E 0E 0E 11 11 11 10 10 10 0B 0B 00080 0B 14 14 14 17 17 17 11 11 11 0F 0F 0F 14 14 14 00090 14 14 14 0D 0F 0F 05 0A 0D 09 10 13 10 15 18 0F 24 位真彩色的 BMP 图文件是由三个部分组成的:位图文件头、位图信息头、位图阵列三个部分组成的。1.1 位图文件头位图文件头就是用来标志这个位图文件一些信息比如:大小、类型等等。共有 14 个字节的信息。下面我们就分别对这 14 个字节的信息分别说明一下它们所代表的意义。42 4D 为位图的标志。如果转换成 ASCII 码的话就是 BM。96 61 02 00 这个双字信息代表着位图文件的总字切数,如果把它转换面十进制的话就是( 00026196 ) H= ( 156054 ) D ,也就是这位图文件的大小是 156054 个字节。00 00 00 00 为保留字。36 00 00 00 表示位图阵列的起始位置,( 00000036 ) H= ( 54 ) D ,也就是从第 54 个字节起就是这幅图的位图阵列了。1.2 位图信息头位图信息头记录着一些关于这幅图的一些基本信息,比如:高度、宽度、分辨率等信息。共占 40 个字节。28 00 00 00 表示着位图信息头的长度,( 00000028 ) H= ( 40 ) D ,即位图信息头的长度占 40 个字节。04 01 00 00 表示位图的宽度,( 00000104 ) H= ( 260 ) D 表示位图的宽度为 260 个像素。C8 00 00 00 表示位图的高度,( 000000C8 ) H= ( 200 ) D 表示位图的高度为 200 个像素。01 00 表示位图设备级别。18 00 位图的色彩级别,( 0018 ) H= ( 24 ) D ,即表示 24 位真彩色。00 00 00 00 表示压缩类型,零表示不压缩。00 00 00 00 位图阵列表字节数。00 00 00 00 表示水平分辨率。00 00 00 00 表示垂直分辨率。00 00 00 00 表示位图实际使用的颜色表中的颜色变址。00 00 00 00 表示位图显示过程中被认为重要颜色变址数。1.3 位图阵列这部分就是这幅图像的主体部分了。其实每幅图像都是由一个一个的点组成的。在位图阵列里就存放着每一个点的颜色信息。每个像素点是由 3 个字节的数据组成的。也就是我们常用到的 RGB 色彩空间每种颜色占一个字节。每个点的颜色都是由蓝色、绿色、红色这个顺序存储的。点的存储顺序是从左到右从下到上,也就是说第一个点是这幅图的第一列的最后一个点(左下角的那个点),之后是它上面的那个点,就这样由下至上直到第一列的第一个点(左上角的那个点),然后是第二列也是从下至上的顺序。直到写完所有的点。2. RGB 和 YCrCb 的转换“颜色空间”的问题我们在后面讲解的一个效果中要用到所以我们在这里简单的讲解一下。 2.1 RGB对一种颜色进行编码的方法统称为“颜色空间”或“色域”。用最简单的话说,世界上任何一种颜色的“颜色空间”都可定义成一个固定的数字或变量。 RGB (红、绿、蓝)只是众多颜色空间的一种。采用这种编码方法,每种颜色都可用三个变量来表示:红色、绿色以及蓝色的强度。记录及显示彩色图像时, RGB 是最常见的一种方案。 2.2 YUV(变称 YCrCb)YUV (亦称 YCrCb )是被欧洲电视系统所采用的一种颜色编码方法(属于 PAL)。 YUV 主要用于优化彩色视频信号的传输。其中“ Y ”表示明亮度( Luminance 或 Luma ),也就是灰阶值;而“ U ”和“ V ”表示的则是色度( Chrominance 或 Chroma ),作用是描述影像色彩及饱和度,用于指定像素的颜色。“亮度”是通过 RGB 输入信号来创建的,方法是将 RGB 信号的特定部分叠加到一起。“色度”则定义了颜色的两个方面—色调与饱和度,分别用 Cr 和 CB 来表示。其中, Cr 反映了 RGB 输入信号红色部分与 RGB 信号亮度值之间的差异。而 CB 反映的是 RGB 输入信号蓝色部分与 RGB 信号亮度值之同的差异。2.3 RGB 与 YcrCb 之间的转换在上面我们已经给大家简单的描述了一下 RGB 和 YcrCb ,下面我们就要讲解一下它们的转换过程。YcrCb 转换到 RGB,注意到 0.299 + 0.587 + 0.114=1.0 三原色的系数之所以不同是因为人的眼睛对不同波长的颜色有着不同的敏感度:Y = 0.299*R + 0.587*G + 0.114*BCb =-0.1687*R - 0.3313*G + 0.5*BCr =0.5*R - 0.4187*G - 0.0813*BRGB 转换回 YcrCb : R = Y+1.402*CrG = Y-0.34414*Cb-0.71414*CrB = Y+1.772*Cb