TIF图像数据结构(转)

TIF图像数据结构之研究

  TIF文件一般由三个部分组成:文件头(简称IFH)、文件目录(简称IFD)、图像数据。

一、图像文件头(Image File Header)
IFH数据结构包含3个成员共计8个字节(见表一):

表一 IFH结构描述
------------------------------------------------------------
名称        字节数 数据类型  说明
------------------------------------------------------------
Byteorder            2    Integer   TIF标记,其值为4D4D或4949
Version              2    Integer   版本号,其值恒为2A00
Offset to first IFD  4    Long      第一个IFD的偏移量
------------------------------------------------------------
表一说明
1.Byteorder:可能是H4D4D或H4949,H4D4D表示该图是摩托罗拉整数格式,H4949表示该图是Intel整数格式。
2.Version:总是H2A00,它可能是tif文件的版本,也可能用于进一步校验该文件是否为TIF格式。
3.Offset to first IFD:第一个IFD相对文件开始处的偏移量(因为可能会有多个顺序排列的IFD)。IFD数据结构并不一定紧跟在IFH后面,相反,它常常位于第三部分图像数据的后面,即TIF图像文件的一般组织形式是:IFH——图像数据——IFD。


二、图像文件目录(Image File Directory)
IFD是TIF图像文件中重要的数据结构,它包含了三个成员。由于一个TIF文件中可以有多个图像,而一个IFD只标识一个图像的所有属性(有的文章把“属性”称之为“标签”),所以,一个TIF文件中有几个图像,就会有几个IFD。IFD的结构见表二:

表二 IFD结构描述
-----------------------------------------------------------------
名称         字节数 数据类型  说明
-----------------------------------------------------------------
Directory Entry Count   2    Integer   本IFD中DE的数量
Directory Entry(1)     12              简称DE,中文译义“目录项”
Directory Entry(2)     12
……
Directory Entry(N)     12
Offset to next IFD      4    Long      下一个IFD的偏移量
-----------------------------------------------------------------
表二说明
1.Directory Entry Count:指出在该IFD中DE的个数;
2.Directory Entry:共12个字节,结构见表三。需要指出的是,DE的个数是不定的,因为每个DE只标识了图像的一个属性,那么这幅图像有N个属性就会有N个DE,用户甚至可添加自定义的标记属性,这就是为什么称TIF格式文件为“可扩充标记的文件”的原因。
3.Offset to next IFD Or NULL:下一个IFD相对于文件开始处的位置,这是一个链式架构。如果该数字为0,表示已经是最后一个IFD。当然,如果该TIF文件只包含了一幅图像,那么就只有一个IFD,显然这个偏移量也会等于0。

表三 DE结构描述
--------------------------------------------------
名称     字节数  数据类型  说明
--------------------------------------------------
tag            2      Integer   本属性的标签编号
type           2      Integer   本属性值的数据类型
length         4      Long      该类型数据的数量
valueOffset    4      Long      属性值的存放偏移量
--------------------------------------------------
表三说明
由DE标识的图像属性有:图像的大小、分辨率、是否压缩、像素的行列数、颜色深度(单色、16色、256色、真彩色)等等。其中:
①tag:是该属性的标签编号(TagID),在图像文件目录中,它是按照升序排列的(但不一定是连续的)。这些编号在TIF格式官方白皮书中可以查到相应的含义,但遗憾的是,我们到哪儿可以找到官方白皮书呢?所以,笔者只能把网上能找得到的资料(再结合自己的实验结果)罗列出来,见表四。
②type:表示该属性值的数据类型,一般认为TIF官方指定的有5种数据类型(但也有说12种数据类型的)。见表五。
③length:该种类型的数据的个数,而不是某个数据的长度。 
④valueOffset:是tagID代表的变量值相对文件开始处的偏移量,但如果变量值占用的空间不多于4个字节(例如只有1个Integer类型的值),那么该值就直接存放在valueOffset中,没必要再另外指向一个地方了。

表四 DE中标签编号的含义
-------------------------------------------------------------------------

TagID  属性名称    type 说明
-------------------------------------------------------------------------
0100  图像宽               0003  单位:像素
0101  图像高               0003  单位:像素
0102  颜色深度             0003  值=1为单色,=4为16色,=8为256色。
如果该类型数据个数>2个,则为真彩图像
0103  图像数据是否压缩   0003  值=05表示压缩
0106  图像是否采用反色显示 0003  值=01表示反色,否则表示不反色 
0111  图像扫描线偏移量   0004  图像数据起始字节相对于文件开始处的位置
0116  图像扫描线的数量     0004  表示图像有几行扫描线,实际上等于图像高度
0117  图像数据字节总数     0003  如果不是偶数,那么实际存放时会在后面加0
011A  水平分辩率偏移量     0005  常用计量单位是:像素/英寸
011B  垂直分辩率偏移量     0005  常用计量单位是:像素/英寸
0131  生成该图像的软件名   0002  文本类型
0132  生成该图像的时间   0002  文本类型
0140  调色板偏移量         0003  256色和16色图像才有此属性,而且有连续2个
调色板,但属性的length值只表示出1个调色板
-------------------------------------------------------------------------
表四说明
①“水平(垂直)分辩率”是分数型的属性,其值要占用8个字节,所以在valueOffset中存放的肯定是它的具体数值的偏移量,而不是数值本身。
②“生成图像的软件名称”和“生成图像的时间”这两个字符型属性,它们的值所占用的空间也会大于4字节,所以在valueOffset中存放的也是它们的值的偏移量,而不是值本身。
③“图像数据字节总数”一般是偶数,如果是奇数,那么实际存放时会在后面加一个0,但这个0不会计算在字节总数之内。

表五 DE中的数据类型
--------------------------------------------------------------------
type值 数据类型  说明
--------------------------------------------------------------------
0001    Byte      
0002    Ascii     文本类型,7位Ascii码加1位二进制0
0003    Integer   
0004    Long      
0005    RATIONAL  分数类型,由两个Long组成,第1个是分子,第2个是分母
--------------------------------------------------------------------


三、图像数据
又称扫描线数据。这些数据可能是压缩的,也可能是未压缩的。如果经过压缩,那么压缩算法又有许多种,所以,图像数据是TIF文件中最为复杂的部分,暂还没有哪个软件能译出所有的压缩算法。


四、一个 Tif 文件的实例
让我们自己动手做一个实验,以加深理性认识。
用系统自带的画图程序新建一个17*15的白色图像,另存为TIF文件,它的全部数据如下(因设备差异你的数据也许会有些微不同):

0000: 49 49 2A 00 4E 00 00 00 80 3F E0 50 38 24 16 0D
0010: 07 84 42 61 50 B8 64 36 1D 0F 88 44 62 51 38 A4
0020: 56 2D 17 8C 46 63 51 B8 E4 76 3D 1F 90 48 64 52
0030: 39 24 96 4D 18 80 80 00 60 00 00 00 01 00 00 00
0040: 60 00 00 00 01 00 00 00 08 00 08 00 08 00 0F 00
0050: FE 00 04 00 01 00 00 00 00 00 00 00 00 01 03 00
0060: 01 00 00 00 11 00 00 00 01 01 03 00 01 00 00 00
0070: 0F 00 00 00 02 01 03 00 03 00 00 00 48 00 00 00
0080: 03 01 03 00 01 00 00 00 05 00 00 00 06 01 03 00
0090: 01 00 00 00 02 00 00 00 11 01 04 00 01 00 00 00
00A0: 08 00 00 00 15 01 03 00 01 00 00 00 03 00 00 00
00B0: 16 01 04 00 01 00 00 00 0F 00 00 00 17 01 04 00
00C0: 01 00 00 00 2F 00 00 00 1A 01 05 00 01 00 00 00
00D0: 38 00 00 00 1B 01 05 00 01 00 00 00 40 00 00 00
00E0: 1C 01 03 00 01 00 00 00 01 00 00 00 28 01 03 00
00F0: 01 00 00 00 02 00 00 00 3D 01 03 00 01 00 00 00
0100: 01 00 00 00 00 00 00 00

简要分析(请注意转换16进制数据时,低位在前,高位在后):

0000-0007:文件头,可以看出,该图是Intel整数格式,第一个IFD的偏移量为4E。
0008-0037:图像数据。注意最后那个0是补加的,它没有统计在“图像数据字节总数”属性值中。
0038-003F:水平分辩率值。
0040-0047:垂直分辩率值。
0048-004D:颜色深度值。
004E-0107:第一个IFD。Directory Entry Count的值(004E-004F)为F,表示这个IFD中有15个DE,每个DE占用12字节,15个DE共占用180字节,加上Directory Entry Count占用的2字节,再加上Offset to next IFD占用的4字节,这个IFD共占用186字节,换算为16进制就是BA,所以,它的数据结束于0107。Offset to next IFD的值(最后4个字节)均为0,表示整幅图像文件只有这一个IFD。其中15个DE的描述见表六。

表六 一个Tif文件实例的DE描述
-------------------------------------------------------------------------
顺号 偏移量 TagID  Type   length valueOffset  说明
--------------------------------------------------------------------------
1   0050  00FE   Long      1      00        未知属性值=0
2   005C  0100   Integer   1      11        图像宽为17像素(10进制)
3   0068  0101   Integer   1      0F        图像高为15像素(10进制)
4   0074  0102   Integer   3      48        颜色深度,其值存放在48-4D
5   0080  0103   Integer   1      05        图像数据是压缩的
6   008C  0106   Integer   1      02        图像不反色显示
7   0098  0111   Long      1      08        图像数据起始字节为8
8   00A4  0115   Integer   1      03        未知属性值=3
9   00B0  0116   Long      1      0F        图像扫描线有15行
10   00BC  0117   Long      1      2F        图像共有47个字节的压缩数据
11   00C8  011A   RATIONAL  1      38        水平分辩率值存放在38-3F
12   00D4  011B   RATIONAL  1      40        垂直分辩率值存放在40-47
13   00E0  011C   Integer   1      01        未知属性值=1
14   00EC  0128   Integer   1      02        未知属性值=2
15   00F8  013D   Integer   1      01        未知属性值=1
--------------------------------------------------------------------------
表六说明
①水平分辩率值存放在0038-003F,占用8个字节,这8个字节是:60 00 00 00 01 00 00 00。由于它是分数类型,前4个字节是分子,其值为60000000,转换为10进制就是96,后4个字节是分母,其值是10000000,转换为10进制就是1,所以,分数值是:96/1,它表示每英寸96像素。
②垂直水平分辩率值存放在0040-0047,请参照①进行分析。
③颜色深度属性,它有3个Integer类型的值,共计6字节,所以valueOffset中存放的也是其值的偏移量。它的属性值存放在0048-004D,3个整形数据值都为8,表示这是一幅24位真彩色的图像。


五、获取tif格式图片宽高度的代码

Sub command1__Click() 
Dim strFile As String     '文件名
Dim strFileType As String 'TIF标记
Dim iffsetIFD As Long     '第一个IFD的偏移量
Dim iCountDE As Integer   'DE的数量
Dim lWidth As Long        '图像宽度
Dim lHeight As Long       '图像高度
Dim Temp1 As Integer, Temp2 As Long, i As Integer, k As Integer

strFile = "D:\1.tif" 
Open strFile For Binary As #1 
strFileType = String(2, 0) 
Get #1, , strFileType     '获取TIF标记
If strFileType <> "II" And strFileType <> "MM" Then Close #1: Exit Sub 
Get #1, , Temp1           '版本号废弃
Get #1, , iffsetIFD       '获取第一个IFD的偏移量
Seek #1, iffsetIFD + 1    '设置下一个读出位置为第一个IFD的偏移量
Get #1, , iCountDE        '获取第一个IFD中DE的数量

For i = 1 To iCountDE 
Get #1, , Temp1         '获取属性的标签编号
If Temp1 = 256 Then     '如果是图像宽
Get #1, , Temp1       '废弃
Get #1, , Temp2       '废弃
Get #1, , lWidth 
k = k + 1 
ElseIf Temp1 = 257 Then '如果是图像高
Get #1, , Temp1       '废弃
Get #1, , Temp2       '废弃
Get #1, , lHeight 
k = k + 1 
Else                    '否则这些数据废弃
Get #1, , Temp1 
Get #1, , Temp2 
Get #1, , Temp2 
End If 
If k = 2 Then Exit For 
Next i

Close #1 
Debug.Print "图像宽:" & lWidth & vbCrLf & "图像高:" & lHeight 
End Sub

posted @ 2010-04-01 00:26  莫忆往西  阅读(645)  评论(0编辑  收藏  举报