回 帖 发 新 帖 刷新版面

主题:[原创]位图文件的数据结构

位图文件的数据结构

一、文件的组成
  Bmp 文件由文件头、位图信息头、调色板、数据区等四个部分组成(真彩位图没有调色板,由三个部分组成),结构如下(在以下所有表格中,偏移量和长度的单位均为字节,括号外为10进制,括号内为16进制):

表一:BMP文件的总体结构
--------------------------------------------------------
      偏移量   长度     说明 
--------------------------------------------------------
1.BMP文件头 000(000) 14 
2.BMP信息头 014(00E) 40          
3.调色板  054(036)  8—1024  8=单色,1024=256色
4.位图数据             又称位图点阵 
--------------------------------------------------------
说明:
  1.上表中1-3部分合称DIB文件头,而2、3两部分又合称为位图信息。
  2.对于单色、16色、256色位图来说,调色板存放的是实际颜色的RGB值,而位图点阵存放的是颜色对应的索引值。
  3.真彩位图没有调色板,在位图点阵存放的是实际颜色的RGB值。

  下面详述各部分的结构。

㈠BMP文件头结构见表二

表二:BMP文件头结构
--------------------------------------------------------------
偏移量  长度  描述      值     说明 
--------------------------------------------------------------
000(000) 2   文件类型     424D    “BM”的 ASCII 码 
002(002) 4   文件大小           以字节为单位 
006(006) 4   保留       00 00 00 00 必须为0 
010(00A) 4   位图点阵偏移量
--------------------------------------------------------------
说明:位图点阵偏移量=表一所述的1—3部分长度之和


㈡BMP信息头结构见表三

表三:BMP信息头结构: 
------------------------------------------------------------------------------
偏移量   长度  描述        值(16进制) 
------------------------------------------------------------------------------
014(00E) 4   BMP 信息头结构长度 28 00 00 00(10进制=40) 
018(012) 4   图像宽度              
022(016) 4   图像高度
026(01A) 2   位面板数      01 00(必须=1) 
028(01C) 2   每象素所占位数   04 00(有6个可能值:1/4/8/10/18/20)
030(01E) 4   象素数据的压缩类型 00 00 00 00(0表示未压缩)
034(022) 4   位图点阵的长度        
038(026) 4   设备水平分辨率
042(02A) 4   设备垂直分辨率
046(02E) 4   有效颜色数     00 00 00 00(调色板中实际使用的颜色索引
                          的个数,O表示全要使用)
050(032) 4   重要的颜色索引个数 00 00 00 00(0表示所有颜色均重要)
------------------------------------------------------------------------------
说明:
  1.上表中的长度数据,遵循“低位在前,高位在后”的原则。并且,凡长度字节数为 2的数据,其数据类型为Integer,字节数为4的数据,其数据类型为Long。
  2.位图点阵长度说明的是图象的大小,而不是整个位图文件的大小。
  3.每象素所占位数是指象素在位图中所占的字节位数(1个字节=8位),01表示单色位图(黑白位图),04表示16色位图,08表示256色,10表示16位加强彩色,18表示24位真彩,20表示32位真彩。
  4.设备水平分辨率和垂直分辨率的单位是:像素/米,实在不知微软为何弄了“米”来做单位,难怪大多数BMP图片的这两个参数都=0。

㈢调色板的结构见表四——表六

表四:调色板的结构
------------------------
颜色  长度 说明
------------------------
蓝(B) 1  蓝色分量 
绿(G) 1  绿色分量 
红(R) 1  红色分量 
保留   1  未用,=0 
------------------------
说明:
  1.单色位图调色板存放着黑色和白色两种颜色值,位图点阵区由1、0两个索引值组成。16色位图调色板存放着16种颜色值,位图点阵区由 0——15的索引值组成。256色位图调色板存放着256种颜色值,位图点阵区存放着0——255的索引值。
  2.由于在调色板中,每种颜色均由蓝、绿、红三个分量组成,加上一个保留字节,所以每种颜色需占用4个字节。

表五:三种位图的调色板数据
-----------------------------------
图标规格 偏移量   长度
-----------------------------------
单色   054(036)   8(4×2)  
16色    054(036)  64(4×16)
256色   054(036) 1024(4×256)
-----------------------------------

表六:VB常用的调色板索引值以及对应的颜色值
----------------------------
颜色 索引值 颜色值 
----------------------------
单色位图:
黑色  0     00 00 00   00
白色  1   FF FF FF   00

16色位图:
黑色  0     00 00 00   00
深红  1     00 00 80   00
深绿  2     00 80 00   00
深黄  3     00 80 80   00
深蓝  4     80 00 00   00
深紫  5     80 00 80   00
深青  6     80 80 00   00
深灰  7     80 80 80   00
浅灰    8     C0 C0 C0   00
红色  9     00 00 FF   00
绿色  A   00 FF 00   00
黄色  B   00 FF FF   00
蓝色  C   FF 00 00   00
紫色  D   FF 00 FF   00
青色  E   FF FF 00   00
白色  F   FF FF FF   00
----------------------------
说明:
  1.每种颜色值占用4个字节,最后一个字节未用。
  2.表三中所说的“每象素所占位数”是指一个像素在位图中所占的字节位数,如果=1, 表示一个像素占用 1位,一个字节可表示8个像素,我们称之为单色位图(黑白位图);如果=4,表示一个像素占用4位,一个字节可表示2个像素,我们称之为16色位图;如果=8,表示一个像素占用8位,一个字节只表示一个像素,我们称之为256色位图。
  3.怎么个对应法呢?举个例来说,比如16色位图的位图点阵区中,某个字节值为81,那就表示该字节所对应的 2个象素,左边的象素索引值=8,对应的颜色为浅灰色,而右边的象素索引值=1,对应的颜色为深红色。


㈣位图点阵的结构

  1.未经压缩的位图点阵数据是按扫描线从下至上存储的,而在每条扫描线中,是从左至右存储的,即图像的第一个像素值,在位图阵列的左下角,最后一个像素值在位图阵列的右上角。
  2.使用调色板的位图,位图点阵区的数据字节高位表示靠左的像素。低位表示靠右的像素。
  3.位图点阵区中,每一条扫描线的长度必须结束于32位的边界,也就是说,一条扫描线的字节长度必须能整除4,否则就要全0字节来补充。举例来说,如果一条扫描线有3个字节,那么就要用空白的1个字节来补充成4字节,如果有6个字节,那么就必须用空白的2个字节来补充成8字节。
  4.位图宽度与扫描线长度的对应关系见表七——表十(图象宽度单位:像素,扫描线长度单位:字节)

表七:单色位图宽度与扫描线长的对应关系
----------------------
图象宽度 扫描线长度
----------------------
 1—32    4
33—64    8
65--96   12
97--120   16
……
----------------------

表八:16色位图宽度与扫描线长的对应关系
----------------------
图象宽度 扫描线长度
----------------------
 1— 8    4
 9—16    8
17--24   12
25--32   16
33--40   20
41--48   24
49--56   28
57--64   32
65--72   36
71--80   40
……
----------------------

表九:256色位图宽度与扫描线长的对应关系
----------------------
图象宽度 扫描线长度
----------------------
 1— 4    4
 5— 8    8
 9—12   12
13—16   16
17--20   20    
21--24   24
25--28   28
29--32    32
33--36   36
37--40   40
41--44   44
45--48   48
……
----------------------

表十:24位真彩位图宽度与扫描线长的对应关系
----------------------
图象宽度 扫描线长度
----------------------
 1     4
 2     8
 3     12
 4     12
 5     16
 6     20
 7     24
 8     24
 9     28
10     32
11     36
12     36
13     40
14     44
15     48
16     48
17     52    
18     56
19     60
20      60
21     64
22     68
23     72
24     72
……
----------------------
说明:
  1.由以上4个表归纳出计算位图一条扫描线长度的VB代码如下∶ 
①单色位图每条扫描线长度=4×(图象宽\32+Abs((图象宽 Mod 32)>0))
②16色位图每条扫描线长度=4×(图象宽\8+Abs((图象宽 Mod 8)>0))
③256色位图每条扫描线长度=4×(图象宽\4+Abs((图象宽 Mod 4)>0))
④24位真彩位图每条扫描线长度=4×(图象宽×3\4+Abs((图象宽×3 Mod 4)>0))
  2.知道了扫描线的长度和图像的高度,我们就可以轻松地计算出位图文件的大小。例如16×16的单色位图,查表七可知,扫描线长度=4,那么位图点阵的大小=高度×扫描线长度=16×4=64,查表五可知,调色板大小=8,查表一可知,BMP文件头大小=14,BMP信息头大小=40,所以,该位图文件的大小=64+8+14+40=126字节。

回复列表 (共2个回复)

沙发

二、三个具体的例子

㈠用系统自带的画图程序制作一个8×8的24位真彩位图,图像为正方形,边框为红色(&H0000FF),中间为浅灰色(&HC4C4C4),其全部数据见表十一。
  我们先来预测一下文件大小:查表十可知,扫描线长度=24,则图像数据长度=8×24=192,查表一可知文件头和信息头长度之和=54,那么文件大小=54+192=246字节。我们根据表十一验证一下。

表十一:8×8的24位真彩位图数据
--------------------------------------------------------
偏移量 数据
--------------------------------------------------------
00:   42 4D F6 00 00 00 00 00 00 00 36 00 00 00 28 00
10:   00 00 08 00 00 00 08 00 00 00 01 00 18 00 00 00
20:   00 00 C0 00 00 00 00 00 00 00 00 00 00 00 00 00
30:   00 00 00 00 00 00 00 00 FF 00 00 FF 00 00 FF 00
40:   00 FF 00 00 FF 00 00 FF 00 00 FF 00 00 FF 00 00
50:   FF C4 C4 C4 C4 C4 C4 C4 C4 C4 C4 C4 C4 C4 C4 C4
60:   C4 C4 C4 00 00 FF 00 00 FF C4 C4 C4 C4 C4 C4 C4
70:   C4 C4 C4 C4 C4 C4 C4 C4 C4 C4 C4 00 00 FF 00 00
80:   FF C4 C4 C4 C4 C4 C4 C4 C4 C4 C4 C4 C4 C4 C4 C4
90:   C4 C4 C4 00 00 FF 00 00 FF C4 C4 C4 C4 C4 C4 C4
A0:   C4 C4 C4 C4 C4 C4 C4 C4 C4 C4 C4 00 00 FF 00 00
B0:   FF C4 C4 C4 C4 C4 C4 C4 C4 C4 C4 C4 C4 C4 C4 C4
C0:   C4 C4 C4 00 00 FF 00 00 FF C4 C4 C4 C4 C4 C4 C4
D0:   C4 C4 C4 C4 C4 C4 C4 C4 C4 C4 C4 00 00 FF 00 00
E0:   FF 00 00 FF 00 00 FF 00 00 FF 00 00 FF 00 00 FF
F0:   00 00 FF 00 00 FF
--------------------------------------------------------
分析∶ 

1.BMP文件头(14字节)
  00-01:值=42 4D,“BM”的ASCII码
  02-05:值=F6 00 00 00,文件大小=246字节
  06-09:保留 
  0A-0D:值=36 00 00 00,位图点阵偏移量=54 

2.BMP信息头(40字节)
  0E-11:值=28 00 00 00,BMP信息头大小=40 
  12-15:值=08 00 00 00,图像宽度=8
  16-19:值=08 00 00 00,图像高度=8
  1A-1B:值=01 00,位面板数=1
  1C-1D:值=18 00,每象素所占位数=24(24位真彩)
  1E-21:值=00 00 00 00,压缩类型=0(无压缩)
  22-25:值=C0 00 00 00,图象数据的长度=192 
  26-29:设备水平分辨率=0 
  2A-2D:设备垂直分辨率=0 
  2E-31:在调色板中实际使用的色彩索引的个数=0 
  32-35:重要的颜色索引个数=0  

3.位图点阵部分(192字节)
  36-4D:位图最末一行的数据,由于是一条红线,所以每个像素的颜色值均为 00 00 FF
  4E-65:位图倒数第二行的数据,该行的首尾2个象素为红色,中间6个象素为浅灰,所以,4E—50字节以及63—65字节为 00 00 FF,而51-62字节均为 C4
  66-DD:位图第二行至第六行的数据,每行占用24字节,分析同上
  DE—F5:位图第一行的数据,参见最末一行的分析


㈡用系统自带的画图程序制作一个16×16的16色位图,图像为正方形,边框为红色(&H0000FF),中间为黄色(&H00FFFF),其全部数据见表十二。
  我们先来预测一下文件大小:查表八可知,扫描线长度=8,则图像数据长度=16×8=128,查表一可知文件头和信息头长度之和=54,查表五可知调色板长度=64,那么文件大小=64+54+128=246字节。我们根据表十二验证一下。

表十二:16×16的16色位图数据
--------------------------------------------------------
偏移量 数据
--------------------------------------------------------
00:   42 4D F6 00 00 00 00 00 00 00 76 00 00 00 28 00
10:   00 00 10 00 00 00 10 00 00 00 01 00 04 00 00 00
20:   00 00 80 00 00 00 00 00 00 00 00 00 00 00 00 00
30:   00 00 00 00 00 00 00 00 00 00 00 00 80 00 00 80
40:   00 00 00 80 80 00 80 00 00 00 80 00 80 00 80 80
50:   00 00 80 80 80 00 C0 C0 C0 00 00 00 FF 00 00 FF
60:   00 00 00 FF FF 00 FF 00 00 00 FF 00 FF 00 FF FF
70:   00 00 FF FF FF 00 99 99 99 99 99 99 99 99 9B BB
80:   BB BB BB BB BB B9 9B BB BB BB BB BB BB B9 9B BB
90:   BB BB BB BB BB B9 9B BB BB BB BB BB BB B9 9B BB
A0:   BB BB BB BB BB B9 9B BB BB BB BB BB BB B9 9B BB
B0:   BB BB BB BB BB B9 9B BB BB BB BB BB BB B9 9B BB
C0:   BB BB BB BB BB B9 9B BB BB BB BB BB BB B9 9B BB
D0:   BB BB BB BB BB B9 9B BB BB BB BB BB BB B9 9B BB
E0:   BB BB BB BB BB B9 9B BB BB BB BB BB BB B9 99 99
F0:   99 99 99 99 99 99
--------------------------------------------------------
分析∶ 

1.BMP文件头(14字节)
  00-01:值=42 4D,“BM”的ASCII码
  02-05:值=F6 00 00 00,文件大小=246字节
  06-09:保留 
  0A-0D:值=76 00 00 00,位图点阵偏移量=121 

2.BMP信息头(40字节)
  0E-11:值=28 00 00 00,BMP信息头大小=40 
  12-15:值=10 00 00 00,图像宽度=16
  16-19:值=10 00 00 00,图像高度=16
  1A-1B:值=01 00,位面板数=1
  1C-1D:值=04 00,每象素所占位数=4(16色)
  1E-21:值=00 00 00 00,压缩类型=0(无压缩)
  22-25:值=80 00 00 00,图象数据的长度=128 
  26-29:设备水平分辨率=0
  2A-2D:设备垂直分辨率=0
  2E-31:在调色板中实际使用的色彩索引的个数=0(全使用)
  32-35:重要的颜色索引个数=0(都重要)  

3.调色板部分(64字节)
  36—75:请对照表六分析

4.位图点阵部分(128字节)
  76-7D:值=99 99 99 99 99 99 99 99, 位图最末一行的数据,由于是一条红线,所以每个像素的颜色索引值均为9
  7E-85:值=9B BB BB BB BB BB BB B9,位图倒数第二行的数据,该行的首尾 2个象素为红色,所以索引值=9,中间14个象素为黄色,所以索引值=B
  86-ED:位图第二行至第14行的数据,每行占8个字节,分析同上
  EE—F5:位图第一行的数据,参见最末一行的分析

板凳

㈢用系统自带的画图程序制作一个16×16的单色位图,图像为正方形,边框为黑色(&H000000),中间为白色(&HFFFFFF),其全部数据见表十三。
  我们先来预测一下文件大小:查表七可知,扫描线长度=4,则图像数据长度=16×4=64,查表一可知文件头和信息头长度之和=54,查表五可知调色板长度=8,那么文件大小=8+54+64=126字节。我们根据表十三验证一下。

表十三:16×16的单色位图数据
--------------------------------------------------------
偏移量 数据
--------------------------------------------------------
00:   42 4D 7E 00 00 00 00 00 00 00 3E 00 00 00 28 00
10:   00 00 10 00 00 00 10 00 00 00 01 00 01 00 00 00
20:   00 00 40 00 00 00 00 00 00 00 00 00 00 00 00 00
30:   00 00 00 00 00 00 00 00 00 00 FF FF FF 00 00 00
40:   00 00 7F FE 00 00 7F FE 00 00 7F FE 00 00 7F FE
50:   00 00 7F FE 00 00 7F FE 00 00 7F FE 00 00 7F FE
60:   00 00 7F FE 00 00 7F FE 00 00 7F FE 00 00 7F FE
70:   00 00 7F FE 00 00 7F FE 00 00 00 00 00 00
--------------------------------------------------------
分析∶ 

1.BMP文件头(14字节)
  00-01:值=42 4D,“BM”的ASCII码
  02-05:值=7E 00 00 00,文件大小=126字节
  06-09:保留 
  0A-0D:值=3E 00 00 00,位图点阵偏移量=62 

2.BMP信息头(40字节)
  0E-11:值=28 00 00 00,BMP信息头大小=40 
  12-15:值=10 00 00 00,图像宽度=16
  16-19:值=10 00 00 00,图像高度=16
  1A-1B:值=01 00,位面板数=1
  1C-1D:值=01 00,每象素所占位数=1(单色)
  1E-21:值=00 00 00 00,压缩类型=0(无压缩)
  22-25:值=40 00 00 00,图象数据的长度=64 
  26-29:设备水平分辨率=0
  2A-2D:设备垂直分辨率=0
  2E-31:在调色板中实际使用的色彩索引的个数=0(全使用)
  32-35:重要的颜色索引个数=0(都重要)  

3.调色板部分(8字节)
  36—3D:值=00 00 00 00 FF FF FF 00,前4个字是黑色的RGB值,后4个字节是白色的RGB值

4.位图点阵部分(64字节)
  3E-41:值=0,位图最末一行的数据,由于是一条黑线,所以每个像素的颜色索引值均为0
  42-45:值=7F FE 00 00,位图倒数第二行的数据,有效值是前2个字节,后2个字节是补充字节。把 7F FE 化为二进制是:0111,1111,1111,1110,该行的首尾 2个象素为黑色,所以索引值=0,中间14个象素为白色,所以索引值=1
  46-79:位图第二行至第14行的数据,每行占4个字节,分析同上
  7A—7D:位图第一行的数据,参见最末一行的分析


三、小实验:改动一个字节,把单色位图由黑白两色改为红白两色
  用Hex编辑器打开任何一个单色位图,把&H38字节的值改为FF,保存,再用看图工具打开,怎么样,是不是颜色已经变了?
  其实我们可以把调色板中有关的6个字节改为任意值!
  由此可知,16色、256色位图(只要是有调色板的图片)都可照此改动。
  而且,我们还可以将此方法用于保密:假如你有一张调色板模式的位图,上面的图像是你的所有的银行密码,你要对图片进行加密,怎么办?你可以试试将调色板中所有的颜色改为同一种颜色值,这样别人看到的就是一张纯色图片,而你要看密码时,只要将调色板中的所有颜色复原即可(你可专门编写一段代码来完成这两项转换工作)。当然,如果你再对位图点阵部分的每个字节都进行异或运算,那简直就成了绝密了!

我来回复

您尚未登录,请登录后再回复。点此登录或注册