Chinaunix首页 | 论坛 | 博客
  • 博客访问: 537217
  • 博文数量: 119
  • 博客积分: 3391
  • 博客等级: 中校
  • 技术积分: 981
  • 用 户 组: 普通用户
  • 注册时间: 2009-03-12 11:49
文章分类

全部博文(119)

文章存档

2014年(3)

2013年(1)

2011年(18)

2010年(27)

2009年(70)

我的朋友

分类: 服务器与存储

2009-03-18 20:57:29

Microsoft Windows 3.0中的画笔(Paintbrush)工具软件为用户提供了强有力的图形绘制和编辑功能,例如图形的旋转、缩放、拼接等[1].利用这些功能可以非常方便地生成所需要的各种复杂的彩色画面.生成的画面以位图文件的格式存储在磁盘上.以此文件为资源,Mircosoft Windows 3.0的支持下,可以在任何需要的时候在任何设备上再现该画面[2].

在实际工作中经常遇到这样的问题:在利用画笔工具软件生成了所需的画面之后,能否脱离开Windows的支持,在其它系统中使用这些画面呢?解决这一问题的关键在于了解位图文件的记录格式.只要了解位图文件的记录格式,这一问题是容易解决的.基于这一目的,文本将详细介绍Mircosoft Windows 3.0位图文件的记录格式.

Microsoft Windows 3.0位图文件(.BMP为扩展名)由以下三个部分组成:

* 位图文件头(BITMAPFILEHEADER)   数据结构

* 位图信息(BITMAPINFO)数据结构

* 位图阵列

.   位图文件头的结构

位图文件头数据结构含有位图文件的类型、大小和打印格式等信息.Windows.h中对其进行了定义:

Typedef struct tagBITMAPFILEHEADER

{

WORD   bfType;              /*位图文件的类型,必须为BM. */

DWORD  bfSize;              /*位图文件的大小,以字节为单位. */

WORD   bfReserved1;        /*位图文件保留字,必须为0. */

WORD   bfReserved2;        /* 位图文件保留字,必须为0. */

DWORD  bfoffbits;           /*位图阵列的起始位置,以相对于位图文件*/

                               /*头的偏移量表示,以字节为单位.*/

}BITMAPFILEHEADER;

.   位图信息的结构

位图信息数据结构含有位图文件的尺寸和颜色等信息.Windows.h中对其进行了定义:  
typedef stuc tagBITMAPINFO

{

BITMAPINFOHEADER   bmiHeader;

RGBQUAD              bmiColor[];

     }BITMAPINFO;

1.bmiHeader是一个位图信息头(BIMMAPINFOHEADER)类型的数据结构,用于说明位图的尺寸. BITMAPINFOHEADER的定义:

typedef struct tagBITMAPINFOHEADER

{

DWORD       BiSize;           /*bmiHeader的长度,以字节为单位.*/

DWORD       biWidth;         /*位图的宽度,以象素为单位.*/

DWORD       biHight;         /*位图的高度,以象素为单位.*/

WORD         biPlanes;        /*目标设备的级别,必须为1.*/

WORD         biBitCount;      /*每个象素所需的位数,必须是1(单色).*/

                                  /*4(16),8(256),24(2^24)之一. */

DWORD       biCompress;      /*位图的压缩类型,必须是0(不压缩).*/

                                   /*1(BI_RLE8压缩类型)2(BI_RLE4压缩类型)之一.*/

DWORD       biSizeImage;     /*位图的大小,以字节为单位.*/

DOWRD       biXPeIsPerMeter;  /*位图的目标设备水平分辨率,以每米象素数为单位.*/

DWORD       biYPeIsPerMeter;  /*位图的目标设备水平分辨率,以每米象素数为单位.*/

DWORD       biCIrUsed;       /*位图实际使用的颜色表中的颜色变址数,详见[3].*/

DWORD       biCIrImprotant;   /*位图显示过程中被认为重要颜色的变址数,详见[3]*/

}BITMAPINFOHEADER;

 

2. bimColor[]是一个颜色表,用于说明位图中的颜色.它有若干个表项,每一表项是一个RGBQUAD类型的结构,定义了一种颜色.RGBQUAD的定义:

Typedef tagRGBQUAD

{

BYTE rgbBlue;

BYTE rgbGreen;

BYTE rgbRed;

BYTE rgbReserved;

}RGBQUAD;

RGBQUAD定义的颜色中,蓝色的亮度由rgbBlue来定,绿色的亮度由rgbGreen来定,红色的亮度由rgbred来定,rgbRserved必须为0.

例如: 若某表项为00,00,FF,00, 那么它定义的颜色为纯红色.

bimColor[]表项的个数由bmBitCount来定:

bmBitCount=1,4,8, bimColor[]分别有2,16,256个项.若某点的象素值为n,则该象素的颜色为bimColor[]所定义的颜色.

bmBitCount=24, bimColor[]的表项为空.位图阵列的每3个字节代表一个像素,3个字节直接定义了象素颜色中蓝、绿、红的相对亮度,因此省去了bimColor[]颜色表.

.   位图阵列的结构

位图阵列记录了位图的每一个象素值.在生成位图文件时,Windows从位图的左下角开始(即从左到右从上到下)逐行扫描位图,将位图的象素值一一记录下来.这些记录象素值的字节组成了位图阵列.

位图阵列有压缩和非压缩两种存储格式.

1.非压缩格式

在非压缩格式中,位图的每一点的象素值值一对应于位图阵列的若干位(bit),位图阵列的大小由位图的宽度,高度及位图的颜色数(bitBITCount)决定.

(1)   位图扫描行与位图阵列的关系

设记录一个扫描行的象素值需n个字节,:

位图阵列的0n-1个字节记录了位图的第一个扫描行的象素值;位图阵列的n2n-1个字节记录了位图的第二个扫描行的象素值;依些类推,位图阵列的(m-1)*nm*n-1个字节记录了位图的第m个扫描行的象素值.位图阵列的大小为n*biHight.

(biWith*bitBITCount)mod32=0:

n=(biWith*biBITCount)/8

(biWith*bitBITCount)mod32!=0:

n=(biWith*biBITCount)/8+4

上式中的+4而不+1的原因是为了使一个扫描行的象素值占用位图阵列的字节数为4的倍数(Windows规定其必须在long边界结束),不足的位用0填充.

(2)位图象素值与位图阵列的关系(以第m扫描行为例)

设记录第m个扫描行的象素值的n个字节分别为:a0,a1,a2,...,:

bitBITCount=1:a0D7位记录了位图的第m个扫描行的第1个象素值,D6位记录了位图的第m个扫描行的第1个象素值,..., D0位记录了位图的第m个扫描行的第8个象素值, a1D7位记录了位图的第m个扫描行的第9个象素值,D6位记录了位图的第m个扫描行的第10个象素值,...

bitBITCount=4:a0D7-D4位记录了位图的第m个扫描行的第1个象素值,D3-D0位记录了位图的第m个扫描行的第2个象素值, a1D7-D4位记录了位图的第m个扫描行的第3个象素值,...

bitBITCount=8:a0D7-D4位记录了位图的第m个扫描行的第1个象素值,a1记录了位图的第m个扫描行的第2个象素值,...

bitBITCount=24:a0,a1,a2位记录了位图的第m个扫描行的第1个象素值,a3,a4,a5记录了位图的第m个扫描行的第2个象素值,...

位图其它扫描行的象素值与位图阵列的对应关系与此类似.

2.   压缩格式

Windows支持BI_RLE8BI_RLE4压缩位图存储格式,减少了位图阵列所占用的磁盘空间.

(1)BI_RLE8压缩格式

bicompression=1,位图文件采用此压缩编码格式.压缩编码以两个字节为基本单位.其中第一个字节规定了用两个字节指定的颜色重复画出的连续象素的数目.

例如,压缩编码05 04表示从当前位置开始连续显示5个象素,5个象素的象素值均为04.

在第一字节为零时,第二字节有特殊的含义:

0:   行末

1:   图末

2:   转义后面的两个字节,用这俩个字节分别表示下一个象素从当前位置开始的水平位移和垂直位移.

n(0x03转义后面的n个字节,其后的n象素分别用这n个字节所指定的颜色画出.注意:实际编码时必须保证后面的字节数是4的倍数.不足的位用0补齐.

例如,压缩编码00 00表示开始新的扫描行,压缩编码00 01表示压缩位图阵列结束,压缩编码00 02 05 01表示从当前位置开始向右移5个象素,向下移1行后再画下一个象素,压缩编码00 03 05 06 07 00表示从当前位置开始连续画3个象素,3个象素的颜色分别为05,06,07,最后面的00是为了保证被转义的字节数是4的倍数.

(2)BI_RLE4压缩格式

bicompression=4,位图文件采用此后压缩编码格式.BI_RLE4的压缩编码格式与BI_RLE8的编码方式类似,维一的不同是:BI_RLE4的一个字节包含了两个象素的颜色.

当连续显示时,第一个象素按字节高四位规定的颜色画出,第二个象素按字节低似位规定的颜色画出,第三个象素按字节高四位规定的颜色画出,...,直到所有象素都画出为止.

例如:压缩编码06 67表示从当前位置开始连续画5个象素,5个象素的颜色分别为6,7,6,7,6.

压缩编码00 04 45 67 00表示从当前位置开始连续画4个象素, 4个象素的颜色分别为4,5,6,7.最后面的00是为了保证被转义的字节数是4的倍数.

.   实例分析

为了更清楚地说明位图文件的格式,下面对存储一个简单划面(如附图所示)的位图文件进行具体分析.画面的底色是蓝色,上面的直线的颜色是黄色,下面的直线的颜色是红色.位图以16色位映象方式存储[1],文件名为DEMO.BMP.debug分析位图文件的内容如下:

186C:0100  42  4D  3E  01  00  00  00  00-00  00  76  00  00  00  28  00

186C:0110  00  00  26  00  00  00  0A  00-00  00  01  00  04  00  00  00

186C:0120  00  00  00  00  00  00  00  00-00  00  00  00  00  00  00  00

186C:0130  00  00  00  00  00  00  00  00-00  00  00  00  80  00  00  80

186C:0140  00  00  00  80  80  00  80  00-00  00  80  00  80  00  80  80

186C:0150  00  00  80  80  80  00  40  40-40  00  00  00  FF   00  00  FF

186C:0160  00  00  00  FF   FF  00  FF   00-00  00  FF  00  FF   00  FF   FF

186C:0170  00  00  FF   FF  FF  00   CC  CC-CC  CC  CC  CC  CC  CC  CC  CC

186C:0180  CC  CC  CC  CC  CC  CC  CC  CC-CC  00  CC  CC  CC  CC  CC  CC

186C:0190  CC  CC  CC  CC  CC  CC  CC  CC-CC  CC  CC  CC  CC  CC  CC  99

186C:01A0  99  99  99  99  99  99  99  99-99  99  99  99  99  99  99  CC

186C:01B0  CC  00  CC  CC  CC  CC  CC  CC-CC  CC  CC  CC  CC  CC  CC  CC

186C:01C0  CC  CC  CC  CC  CC  00  CC  CC-CC  CC  CC  CC  CC  CC  CC  CC

186C:01D0  CC  CC  CC  CC  CC  CC  CC  CC-CC  00  CC  CB  BB  BB  BB  BB

186C:01E0  BB  BB  BB  BB  BB  BB  BB  BB-BB  BB  BB  BC  CC  00  CC  CC

186C:01F0  CC  CC  CC  CC  CC  CC  CC  CC-CC  CC  CC  CC  CC  CC  CC  CC

186C:0200  CC  00  CC  CC  CC  CC  CC  CC-CC  CC  CC  CC  CC  CC  CC  CC

186C:0210  CC  CC  CC  CC  CC  00  CC  CC-CC  CC  CC  CC  CC  CC  CC  CC

186C:0220  CC  CC  CC  CC  CC  CC  CC  CC-CC  00  CC  CC  CC  CC  CC  CC

186C:0230  CC  CC  CC  CC  CC  CC  CC  CC-CC  00  CC  CC  CC  00  00  00

                (0,0)

                  ┌───────────┐

                  (3,4)   (黄色)         (35,4)  

                  _____________________  

                                                               

                                                               

                  (2,7)   (红色)         (34,7)  

                  _____________________    

                  └───────────┘  

                                                                (38,10)  

                        附图       实例画面  

其中:

0100-010DBITMAPFILEHEADER数据结构,它说明了如下的信息:位图文件共318B (bfSize=0x013E),位图阵列从0176处开始(bfoffBits=0x76).

010E-0135BITMAPFILEHEADER数据结构,它说明了如下的信息:BITMAPFILEHEADER28B(biSize=0x28),位图的大小为38X10(biWith00x26, biHight=0x0A,以象素为单位)

位图阵列的每四位表示一个象素,位图有16种颜色, bmiColor[]16个表项(bitBITCount=4),位图采用非压缩存储方式(bitCompression=0);

0136-0175bmiColor[]颜色表,每四个字节定义一种颜色,64B,定义了16种颜色.其中第九个表项(015A-015D)定义了红色,11表项(0162-0165)定义了黄色,12个表项(0166-0169)定义了蓝色.

0176-023D是位图阵列,位图每个扫描行有38个象素,对应位图阵列中的20个字节,其中第20个字节被填0,以保证字节数是4的倍数.黄线在位图的第6扫描行,此行对应位图阵列的01DA-01ED字节,红线在位图的第3行扫描,此行对应位图阵列的0192-01B1字节,位图共有10个扫描行.

阅读(3735) | 评论(1) | 转发(0) |
0

上一篇:处理位图

下一篇:fseek函数

给主人留下些什么吧!~~

landaship2014-04-04 17:38:12

好复杂,我就想找一个显示bmp的简单的例子,但是很多都是显示的不正确的,有很多不明白的地方,还得仔细看啊