对图像文件(jpg和tif)中各种属性存放方式的研究

来源:互联网 发布:js input数组 编辑:程序博客网 时间:2024/05/17 21:06

[转载]对图像文件(jpg和tif)中各种属性存放方式的研究

来源:http://blog.sina.com.cn/s/blog_bf9655770102vqhk.html

北京蓝码动力软件科技有限公司 余承飞

2015-05-20

交流QQ: 1931045538

1        研究背景

客户被jpg和tif文件中存在的各种附加属性—Exif属性、XMP属性、TIFF属性搞晕了,这些属性有些时候自相矛盾,特别是分辨率属性,不知道Photoshop会按照那个属性值来进行打印输出和其它处理。因此客户委托我研究一下。

我在网上找了很多资料,通过做一些小实验进行验证,基本上有了一些成果,在本文中记录下来。如有错误,希望大家指正。

2        TIFF中的各种属性

2.1      开始

本来我是先去研究JPEG的,后来发现JPEG里面其实套用了TIFF的数据的表示方法,所以TIFF是JPEG文件存储方式和EXIF的基础,因此我还是先说TIFF,再说JPEG。

用Photoshop打开一个tif文件看看。我选了这么一张:


在Photoshop CS5中选菜单“文件/文件简介”:

选中“高级”选项卡:

我原先以为这个界面显示的是Exif、Tiff、XMP属性,但经过后面的分析,发现这个界面显示的其实都是从XMP信息段中取出来的信息。因此,我在后面又补充了对非PhotoShop产生的tif文件的分析。

客户只关心EXIF属性、TIFF属性、XMP属性,我也就只研究这几项。

2.2      TIFF属性

首先,TIFF属性最重要,不能乱改。EXIF属性和XMP属性其实都可以删了不要。

TIFF文件的格式说明是TIFF6.pdf,可以从我公司网站的下载中心下载:

http://www.xcoolsoft.com/cn/downloads.php

TIFF文件的结构如下图:


TIFF文件首先有一个8个字节的文件头,然后跟着一个IFD,也就是Image File Directory的缩写,可以看做是索引目录。IFD可以有很多个,文件头指出了第一个IFD的位置,在IFD的结尾处指出了下一个IFD的位置,这样一直链接下去。

每个IFD的开始处首先说明了这个IFD有多少个Directory Entry,也就是有多少条目。然后顺序跟着这么多个条目,每个条目占12个字节。

在每个条目的12个字节里面,前两个字节是Tag(标签),标签的数值就决定了这个条目是干什么的。在TIFF6.pdf的最后附录中,列出了TIFF中的所有标签。我们在PhotoShop中看到的TIFF属性,都有相应的标签,如下表所示:


 

2.3      Exif属性

那么,Exif属性是如何存放的呢? 这要看另一个文档:exifStandard2.pdf。这个文档同样也可以从我公司网站的下载中心下载:

http://www.xcoolsoft.com/cn/downloads.php

Exif属性信息专门放在一个IFD里,称为Exif IFD。它的Tag是34665(8769.H)。下面是如何找到这个IFD的过程。

我们用二进制编辑器打开这个tif文件,找到第一个IFD:


这个文件的编码是低位在前的。第一个IFD的头两个字节是17 00,反过来就是0x0017,也就是说有0x17=23个Entry。上图中每个用红线标出的是每个Entry的标签(Tag),红线标注的最后四个字节是下一个IFD的地址,因为都是0,所以就只有这一个IFD。

请注意里面有一个标签是69 87,反过来是0x8767,就是Exif IFD的Tag。这个Entry的最后四个字节是E0 97 0F 00,也就是0x000F97E0,是Exif IFD的地址,从文件的开头开始计算。我们跳到这个地址看看。


03 00表示有3个Entry。把这些标签解释一下:


与PhotoShop中的属性显示完全一致。

2.4      XMP属性

XMP在各种文件中的存放位置:


XMP插入tif文件的Tag是700,即0x02BC。在我们的这个tif文件中,有BC 02这个Tag,Type=0x0001,即“BYTE”;Count=0x00003D21,Offset=0x00000262。我们跳到这个地址看看。


果然,这个地址开始是文本形式的xml。

3        JPEG 中的各种属性

3.1      开始

我们使用Win7自带一张jpg图片作为研究对象。这个图片的位置如下:


用PhotoShop CS5打开看一下:


我原先以为这个界面显示的是Exif、Tiff、XMP属性,但经过后面的分析,发现这个界面显示的其实都是从XMP信息段中取出来的信息。因此,我在后面又补充了对非PhotoShop产生的jpg文件的分析。

下面我们分析一下这些属性信息都放在哪里了。

3.2      JPEG文件格式

Wiki:

http://en.wikipedia.org/wiki/JPEG

http://en.wikipedia.org/wiki/JPEG_File_Interchange_Format

详细的格式说明,大家有兴趣的话可以去仔细研究一下。下面是我的理解。首先上一张从Wiki截下来的文件结构图:


这里提到了“JFIF”。JFIF大概是一个标准,规定了JPEG文件应该怎么存储。后来又有了Exif标准,也规定了JPEG怎么存储。软件厂商们就把这两个标准综合了一下,先以JFIF为基础,然后把Exif中的扩展的东西加进去,再把ICC Color Profiles加进去。

下面这张图是从Exif标准中截下来的:


有兴趣研究的朋友,建议先看TIFF标准,然后再看Exif标准,这样就容易理解得多了。Exif标准中对很多术语都不解释,例如IFD,完全没有解释,意思是详情参见TIFF标准。

言归正传。JPEG文件开头是SOI,即Start of Image(图像开始),必须是FF D8,规定死的。接下来是一些数据段,首先都是用两个字节(marker)表示这个数据段是什么,如下图:



我们关心的Exif信息是在APPn里面。

对照我们的这个jpg文件看一下:


头两个字节是FF D8没错。

3.2.1      APP0(0xFFE0)

接下来,我们发现marker是FF E0,即APP0。我们看看JFIF 的APP0是什么结构,如下图。


APP0 marker就是FF E0,跟我们的文件对上了。接下来是:

Length=0x0010=16

Iditifier=”JFIF\0” (0x4A46494600)

Version=0x0102 (major version=0x01, minorversion=0x02)

Density units = 0x01 (Pixels per inch)

X density = 0x0060=96

Y density = 0x0060=96

Thumbnail width (tw) = 0x00

Thumbnail height (th) = 0x00

Thumbnail data: 0个字节,不存在。

算下来总长度:2+5+2+1+2+2+1+1=16,与Length相符。

3.2.2      APP14(0xFFEE)

我们继续向下探索这个文件。

FFEE:APP14。怀疑是Adobe信息。

0x000E:怀疑是这段信息的长度。0x000E=14字节。

3.2.3      APP1(0xFFE1)

再向下:

FFE1:APP1。应该是Exif了。

到这里要看Exif标准了。

Length=0x135D=4957

Exif Identifier Code = “Exif\0\0” =0x457869660000 (是应该有两个“\0”吗?没找到证据)

以下开始是TIFF Header。前面我们已经学习过TIFF的格式,这里就很容易看懂了。

Byte Order = 0x4D4D (“MM”), bigendian,高位在前,不用反过来看了。

42: 0x002A TIFF固定标志,必须是这个。

Offset of IFD = 0x00000008,也就是立即开始0thIFD

number of fields = 0x0007,有7个Entries。

Entry 1

Tag = 0x0132 (DateTime)

Type = 0x0002,(ASCII)

Count = 0x00000014 = 20

Value or Offset = 0x00000062 = 98,因为20个字节放不下,这个98是偏移地址,从TIFF头开始算起。TIFF头的起始地址为0x00002E,相加后得0x000090。

跳到0x00000090看一下:

刚好是文本形式的拍摄时间。

再向下,第二个Entry:

Entry 2

Tag = 0x013B (Artist)

Type = 0x0002,(ASCII)

Count = 0x00000007

Value Offset = 0x00000076,加上TIFF头偏移0x2E,绝对偏移为0xA4。

 

到0xA4看一下:

是文本“Corbis”。奇怪的是,PhotoShop中的Exif属性中没有这一项。在Windows的属性中可以看到这项,如下图:

再向下:

Entry 3

Tag = 0x4746 这个标记在Exif标准中没有找到。查了别的网站,说是“Rating”。

Type = 0x0003,(SHORT)

Count = 0x00000001

Value Offset = 0x00040000 = 4 这直接就是数值了,Rating = 4

 

在Windows的属性中可以看到“分级”为4颗星。

再向下:

Entry 4

Tag = 0x4749 (RatingPercent) 查到,Exif标准中没有。

Type = 0x0003,(SHORT)

Count = 0x00000001

Value Offset = 0x003F0000 = 63,即RatingPercent =63%

 

再向下:

Entry 5

Tag = 0x9C9D (XPAuthor, ignored by Windows Explorer if Artist exists )

Type = 0x0001,(BYTE)

Count = 0x0000000E = 14

Value or Offset = 0x00000000 = 0 偏移地址竟然是0,不可理解。就当废弃了吧。

 

再向下:

Entry 6

Tag = 0xEA1C (Padding)

Type = 0x0007,(UNDEFINED)

Count = 0x0000080C

Value or Offset = 0x00000000 = 0 也是无效的偏移

 

最后一个Entry:

Entry 7

Tag = 0x8769 (Exif IFD Pointer)

Type = 0x0004,(LONG)

Count = 0x00000001

Value or Offset = 0x0000007D,这是一个Exif IFD的地址偏移。本来这个IFD就是用来存Exif信息的了,这又出来另一个Exif IFD,好复杂。

 

最后就是指向下一个IFD地址了,4个字节,如下图:

4-byte offset to the next IFD = 0x000000E7,加上TIFF头地址0x2E,绝对地址为0x115。到这个地址看看。

这个地址竟然是奇数的,不是Word对齐的。

Entry数量=0x0005

Entry 1

Tag = 0x0103 (Compression)

Type = 0x0003,(SHORT)

Count = 0x00000001

Value or Offset = 0x00060000, 这就是数值了,Compression=6。

 

查了Exif标准后,发现这个IFD是用来存缩略图的。标准中的解释如下:

向下:

Entry 2

Tag = 0x011A (XResolution)

Type = 0x0005,(RATIONAL,即两个LONG,第一个是分子,第二是分母)

Count = 0x00000001

Value or Offset = 0x00000129, 因为2个LONG在这里放不下,所以这个是offset(偏移)。加上TIFF头地址0x2E,绝对偏移为0x157。

 

到地址0x157看看。如下图:

分子=0x00000048=,分母=0x00000001。即72/1。

向下:

Entry 3

Tag = 0x011B (YResolution)

Type = 0x0005,(RATIONAL)

Count = 0x00000001

Value or Offset = 0x00000131, 加上TIFF头地址0x2E,绝对偏移为0x15F。

 

到地址0x15F看看。如下图:

跟前面一样,也是72/1。

向下:

Entry 4

Tag = 0x0201 (JPEGInterchangeFormat,这里表示缩略图的位置)

Type = 0x0004,(LONG)

Count = 0x00000001

Value or Offset = 0x00000139。加上TIFF头地址0x2E,绝对偏移为0x167。

 

到地址0x167看看。如下图:

FF D8是SOI,FF E0是APP0,明显是一个jpg的特征。这应该是缩略图没错。

向下:

Entry 5

Tag = 0x0202 (JPEGInterchangeFormatLength,这里表示缩略图的长度)

Type = 0x0004,(LONG)

Count = 0x00000001

Value or Offset = 0x0000121C

 

接下来是00 00 00 00,表示没有下一个IFD了。

回头再看0th IFD的Exif IFD Pointer,其偏移为0x0000007D,加上TIFF头地址0x2E,绝对偏移为0xAB。到这个地址看看。

Entry 数量=0x0005。

Entry 1

Tag = 0x9003 (DateTimeOriginal)

Type = 0x0002,(ASCII)

Count = 0x00000014=20

Value or Offset = 0x000000BF。加上TIFF头地址0x2E,绝对偏移为0xED。

 

到地址0xED看看。

这是时间日期没错。这跟我们前面看到的Tag=0x0132的时间不一样,那个是2009年的,这个是2008年的。

往下:

Entry 2

Tag = 0x9004 (DateTimeDigitized)

Type = 0x0002,(ASCII)

Count = 0x00000014=20

Value or Offset = 0x000000D3。加上TIFF头地址0x2E,绝对偏移为0x101。

 

到地址0x101看看:

这是数字化的时间。

往下:

Entry 3

Tag = 0x9291 (SubSecTimeOriginal)

Type = 0x0002,(ASCII)

Count = 0x00000003

Value or Offset = 0x35340000=“54\0\0”。表示54亚秒。

 

往下:

Entry 4

Tag = 0x9292 (SubSecTimeDigitized)

Type = 0x0002,(ASCII)

Count = 0x00000003

Value or Offset = 0x35340000=“54\0\0”。表示54亚秒。

 

往下:

Entry 5

Tag = 0xEA1C (Padding) 用来垫的,没意义的。

Type = 0x0007,(UNDEFINED)

Count = 0x000007B4

Value or Offset = 0x00000000

 

指向下一个IFD的指针为00 00 00 00,说明没有其它了。

这样就把APP1分析完了。

3.2.4      APP12 (0xFFEC)

APP1的长度是0x135D,起始地址是0x26,所以下一段的开始地址是0x135D+0x26=0x1383。到这个地址看看:

这一段是Adobe Photoshop产生的,跟“Save for Web”有关。

3.2.5      APP1 (0xFFE1)

接下来又是一段APP1。

这一段应该就是传说中的XMP基本属性吧。

Length=0x1014

起始地址为0x1398,0x1398+0x1014=0x23AC。跳到这个地址看看。

3.2.6      APP13 (0xFFED)

这段是“Photoshop IRB”,不深究了。

Length = 0x00DC。起始地址0x23AE,0x23AE+0x00DC=0x248A。跳到这个地址。

3.2.7      DQT(0xFFDB)

这段是“Define Quantization Table”,不深究了。

Length=0x0043。起始0x248C,下个地址是0x0043+0x248A=0x24CF。跳到这个地址。

3.2.8      DQT(0xFFDB)

又是一段DQT。

Length=0x0043, 起始地址0x24d1,下一地址0x0043+0x24d1=0x2514。跳到这个地址。

3.2.9      SOF (0xFFC0)

Length=0x0011,起始地址0x2516,下一地址0x0011+0x2516=0x2527。跳到这个地址。

3.2.10 DHT (0xFFC4)

Length=0x001F,起始地址0x2529,下一地址0x001F+0x2529=0x2548。跳到这个地址。

3.2.11 DHT (0xFFC4)

Length=0x00B5,起始地址0x254A,下一地址0x00B5+0x254A=0x25FF。跳到这个地址。

3.2.12 DHT (0xFFC4)

Length=0x001F,起始地址0x2601,下一地址0x0011+0x2601=0x2620。跳到这个地址。

3.2.13 DHT (0xFFC4)

Length=0x00B5,起始地址0x2622,下一地址0x00B5+0x2622=0x26D7。跳到这个地址。

3.2.14 SOS (0xFFDA)

 

Length=0x000C,起始地址0x26D9,下一地址0x000C+0x26D9=0x26E5。从这开始就是图像数据了。

4        补充分析:非PhotoShop产生的图片

4.1      TIFF

首先我想到的是Windows的画图。

打开画图软件,就用默认的100x100大小,什么也不画,选格式为TIFF存盘。如下图。

关闭画图,分析一下这个tif文件。

因为文件很小,只有998字节,所以翻一页就看完了,里面没有出现XMP文本,是一个“纯”的TIFF。用PhotoShop打开来看看:

奇怪的是,XMP属性就存在了。所以用PhotoShop来看文件的属性是不正确的,我猜PhotoShop是获取了文件中的原有的属性,然后加上了一些默认的Adobe、XMP、都柏林属性,存盘的时候就以XMP信息段的形式存在文件里了。

4.2      JPEG

我想到了用数码相机拍摄的jpg照片。打开一个看看:

翻了一遍,没有发现XMP信息。用PhotoShop打开:

可以看到有Exif属性。

所以,不能用PhotoShop去看文件中是否存在Adobe、XMP等属性,这样不准确。

0 0