关于图片中的位之一 位图格式、编码与显象原理

转自http://virus.blog.51cto.com/51437/18784 

       位图格式、编码与显象原理
Windows已经把位图技术深入运用在系统的各个方面。比如在Windows中,你在记事本,
写子板里打出来的字实际上是利用位画原理"画"出来的。许多Windows可执行程序有美丽
的图标,其实它是将位图技术嵌入可执行文件EXE中。图标也是利用位图原理构造的,微
软的最新的操作系统WindowsXP对位图的运用更是精妙绝伦... ...好了我们现在先放下
位图原理运用方面多姿多彩的变化,来研究下最基本的Windows画笔产生的画图编码以及
画图产生的原理。以下分析都是针对Windows画笔画产生的24位真彩色位图格式。
下面我们将解析一幅位图的十六进制代码来介绍位图的格式。在Windows画笔中创建一幅
24位真彩色的位图,将其高设为10象素,宽为5象素小位图,用红色填充,然后将其保存
到磁盘上。最后用16进制编程器打开,可以看到以下位图的十六进制格式:
Offset 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
00000000 42 4D D6 00 00 00 00 00 00 00 36 00 00 00 28 00 BM?......6...(.
00000016 00 00 0A 00 00 00 05 00 00 00 01 00 18 00 00 00 ................
00000032 00 00 A0 00 00 00 C4 0E 00 00 C4 0E 00 00 00 00 ..?..?..?....
00000048 00 00 00 00 00 00 00 00 FF 00 00 FF 00 00 FF 00 ........?..?..?.
00000064 00 FF 00 00 FF 00 00 FF 00 00 FF 00 00 FF 00 00 ?..?..?..?..?..
00000080 FF 00 00 FF 00 00 00 00 FF 00 00 FF 00 00 FF 00 ..?....?..?..?.
00000096 00 FF 00 00 FF 00 00 FF 00 00 FF 00 00 FF 00 00 ?..?..?..?..?..
00000112 FF 00 00 FF 00 00 00 00 FF 00 00 FF 00 00 FF 00 ..?....?..?..?.
00000128 00 FF 00 00 FF 00 00 FF 00 00 FF 00 00 FF 00 00 ?..?..?..?..?..
00000144 FF 00 00 FF 00 00 00 00 FF 00 00 FF 00 00 FF 00 ..?....?..?..?.
00000160 00 FF 00 00 FF 00 00 FF 00 00 FF 00 00 FF 00 00 ?..?..?..?..?..
00000176 FF 00 00 FF 00 00 00 00 FF 00 00 FF 00 00 FF 00 ..?....?..?..?.
00000192 00 FF 00 00 FF 00 00 FF 00 00 FF 00 00 FF 00 00 ?..?..?..?..?..
00000208 FF 00 00 FF 00 00 ?..?..
以上即基本的一幅真彩色24位宽10象素高5象素的位图的十六进制格式。我们可以把一幅
位图分为三部分来研究:位图文件头,位图信息头和位图阵列表。
一、位图文件头:
Offset 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
00000000 42 4D D6 00 00 00 00 00 00 00 36 00 00 00 BM?......6...
分析:位图文件头,记录标志文件大小等一些信息。
42 4D 为位图的标志,即ASCII码为BM。
D6 00 表示位图的文件的总字节数。换算成十进制为15054字节,即这幅画的大小为150
54字节。
00 00 00 00 00 00 该几个字节为保留字节。
36 00 00 00 表示位图阵列的起始位置。36H=54即54字节开始为位图阵列
二、位图信息头:
Offset 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
00000000 28 00 (.
00000016 00 00 0A 00 00 00 05 00 00 00 01 00 18 00 00 00 ................
00000032 00 00 A0 00 00 00 C4 0E 00 00 C4 0E 00 00 00 00 ..?..?..?....
00000048 00 00 00 00 00 00 .......
分析:位图信息头,记录着和位图相关的一些信息。如位图长、宽、高等。
28 00 00 00 位图信息头的长度。28H=40,即位图信息头占用40个字节。
0A 00 00 00 位图宽度。我们建立的位图是10个象素所以这里为0AH。
05 00 00 00 位图高度 。刚好等于我们建立位图时设置的5个象素宽的值。
10 00 位图设备级别。
18 00 位图级别00 18H=24即24位真彩色。
00 00 00 00 压缩类型 为0代理不压缩。
A0 00 00 00 位图大小。A0=160 ,代表下面的图阵列表为160个字节
C4 0E 00 00 水平分辨率。
C4 0E 00 00 垂真分辨率。
00 00 00 00 位图实际使用的颜色表中的颜色变址数。
00 00 00 00 位图显示过程中被认为重要颜色变址数。
三、位图阵列表
Offset 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
00000048 00 00 FF 00 00 FF 00 00 FF 00 .?..?..?.
00000064 00 FF 00 00 FF 00 00 FF 00 00 FF 00 00 FF 00 00 ?..?..?..?..?..
00000080 FF 00 00 FF 00 00 00 00 FF 00 00 FF 00 00 FF 00 ..?....?..?..?.
00000096 00 FF 00 00 FF 00 00 FF 00 00 FF 00 00 FF 00 00 ?..?..?..?..?..
00000112 FF 00 00 FF 00 00 00 00 FF 00 00 FF 00 00 FF 00 ..?....?..?..?.
00000128 00 FF 00 00 FF 00 00 FF 00 00 FF 00 00 FF 00 00 ?..?..?..?..?..
00000144 FF 00 00 FF 00 00 00 00 FF 00 00 FF 00 00 FF 00 ..?....?..?..?.
00000160 00 FF 00 00 FF 00 00 FF 00 00 FF 00 00 FF 00 00 ?..?..?..?..?..
00000176 FF 00 00 FF 00 00 00 00 FF 00 00 FF 00 00 FF 00 ..?....?..?..?.
00000192 00 FF 00 00 FF 00 00 FF 00 00 FF 00 00 FF 00 00 ?..?..?..?..?..
00000208 FF 00 00 FF 00 00 ?..?..
分析:该区域均为位图阵列表。
在24位位图阵列中,每三个字节代表画笔上的一个象素,这三个字节从左到右分别代表
蓝、绿、红,所以00 00 FF代表一个红色的象素。在位图阵列中就记载了位图显示的位
置和颜色这两个要素。在此例中地址为48开始的三个字节00 00 FF在画笔中呈出来的是
左下角的最左边的一个点。虽然和实际上的位图有所不同但它是按一定规律的。
核心成象原理:
在24位位图阵列表中,每三个字节产生屏幕上的一个象素,每个字节分别控制着蓝、绿
、红三个电子枪的发光强度。我们知道在显示器内部有三个电子枪,如果这三个电子枪
都不发光的情况下这时屏幕上就显示为黑色,此时这三个字节就应该为00 00 00;如果
三个电子枪都各自发最强的光,即产生最强的蓝、绿、红三种光混合在一起就是白色,
这时位图阵列表的三个字节为FF FF FF;如果只是其中的一个电子枪发光则产生的光就
是蓝、绿、红中的其中的一种;如果系统需要其它颜色的话就可能两个或者三个电子枪
都产生强弱不同的光线来组合成其它颜色。在位图阵列表中的这三个字节只是告诉电子
枪要发光的强弱,00代最不发光,FF代表发该电子枪最强的光,这就是为什么这么一段
位图阵列表为什么能够在画笔中呈现出多彩的颜色的基本原理。
以上仅对Windows画笔产生的24位真彩色位图的一个例子来解析位图格式。在VC中的win
gdi.h中对于位图的编码和格式有更加详细的定义,下面给出24位真彩位图格式在VC中的
定义。
typedef struct tagBITMAPFILEHEADER { //位图文件头
WORD bfType; //位图标志"BM"
DWORD bfSize; //位图文件总字节数
WORD bfReserved1;
WORD bfReserved2;
DWORD bfOffBits;
} BITMAPFILEHEADER, FAR *LPBITMAPFILEHEADER, *PBITMAPFILEHEADER;
typedef struct tagBITMAPINFOHEADER{ //位图信息头格式的定义
DWORD biSize; //位图住息头占用字节数
LONG biWidth; //位图呈象宽度
LONG biHeight; //位图呈象高度
WORD biPlanes; //位图设备级别
WORD biBitCount; //位图级别设定
DWORD biCompression; //压缩类型
DWORD biSizeImage; //位图阵列表字节数
LONG biXPelsPerMeter; //水平分辨率
LONG biYPelsPerMeter; //垂真分辨率
DWORD biClrUsed; //位图实际使用的颜色表中的颜色变址数
DWORD biClrImportant; //位图显示过程中被认为重要颜色变址数
} BITMAPINFOHEADER, FAR *LPBITMAPINFOHEADER, *PBITMAPINFOHEADER;
typedef struct tagRGBTRIPLE { //位图阵列格式定义
BYTE rgbtBlue; //定义蓝色
BYTE rgbtGreen; //定义绿色
BYTE rgbtRed; //定义红色
} RGBTRIPLE; //构成一个3字节的RGBTRIPLE

你可能感兴趣的:(编码)