从图片获取信息必须要有Exif字段信息,而Exif只存在于jpeg和tiff格式中
jpeg:开头 FF D8 FF E1
tif: 开头 49 49
JPEG图片的EXIF数据
EXIF JPEG文件将EXIF信息存储在JFIF的APP1标记中。
EXIF主要保存拍摄照片时的相机参数、图像缩略图、GPS信息等。
EXIF在JPEG图片中的存储位置
EXIF 存储在JPEG图片的 APP1标记中,符合JFIF标准。APP1标记的格式包含三部分:标记 (0xFFE1)、数据长度、数据内容。
存储了EXIF的APP1标记通常包含:标记 (0xFFE1)、数据长度、EXIF标示符、EXIF数据。
也就是说,EXIF APP1 在数据内容起始(即紧跟数据长度之后),设置Exif标示符 (“Exif\0\0”),标示该APP1 中的数据是EXIF数据。
EXIF标示符是为了与其它也使用 APP1标记的数据(如XMP)区分。
JPEG图片中存储的EXIF如图:
Fig.1. Basic Structure of JPEG Files.
一个典型的EXIF JPEG文件
一个典型的EXIF JPEG文件结构类似下面这样:
|
我们可以简化一下,看一个只包含主要IFD和JPEG 格式的缩略图的APP1结构("Intel"字节序)。
就像上面描述的那样, Exif 数据开始于ASCII字符 "Exif" 和2个字节的0x00, 后面才是 Exif的数据.
缩略图数据存储在IFD1的数据域.
FFE1 | APP1 标记 | ||||
SSSS | APP1 数据 | APP1 数据大小 | |||
45786966 0000 | Exif 头 | ||||
49492A00 08000000 | TIFF 头 | ||||
XXXX. . . . | IFD0 (主图像) | 目录 | |||
LLLLLLLL | 连接到 IFD1 | ||||
XXXX. . . . | IFD0的数据域 | ||||
XXXX. . . . |
| Exif 子IFD | 目录 | ||
00000000 | 连接结束 | ||||
XXXX. . . . | Exif 子IFD的数据域 | ||||
XXXX. . . . |
| Interoperability IFD | Directory | ||
00000000 | 连接结束 | ||||
XXXX. . . . | Interoperability IFD的数据域 | ||||
XXXX. . . . | Makernote IFD | Directory | |||
00000000 | 连接结束 | ||||
XXXX. . . . | Makernote IFD的数据域 | ||||
XXXX. . . . | IFD1(缩略图像) | 目录 | |||
00000000 | 连接结束 | ||||
XXXX. . . . | IFD1的数据域 | ||||
FFD8XXXX. . . XXXXFFD9 | 缩略图像 |
需要说明的是,尽管 JPEG 数据仅仅是使用 Motorola 字节序, 但 Exif 却是允许Intel字节序 和 Motorola 字节序这两种字节序存在的。
EXIF中的IFD结构
EXIF遵循TIFF文件格式,并对TIFF格式做了一些扩展。
因此EXIF也是一种非常灵活的格式,具有非常好的可扩充性,要想较好地处理其中的相关数据也是比较麻烦的。
标准的TIFF格式在 上篇中讲到。简单回顾一下TIFF格式中的IFD。
IFD是一个链表结构,如图所示。在每个IFD的末尾包含一个指向下一个IFD的偏移量(同样是从TIFF Header算起),如果这个偏移量为0,则表示已经到了链表的末尾。
图 TIFF格式中的IFH和IFD链表结构
在Exif格式中,只有两个标准IFD。第一个IFD 是IFD0(主图像IFD), 然后它连接到IFD1(缩略图IFD) ,并且IFD 连接在此结束。IFD0/IFD1 不包含任何的数字相机的信息,例如快门速度, 焦距等.
在IFD0中除了自己的DE外,还包括了EXIF自定义的EXIF Sub IFD、GPS IFD,而EXIF sub IFD中又进一步包括了Interoperability IFD(简称IOP)和MakerNote IFD。
EXIF自定义IFD的结构与标准TIFF IFD相同,但不是记录于TIFF的IFD链表中,而是 作为TIFF IFD的子链表形式存在(因为扩展IFD里定义了不同于TIFF标准的Tag,这样为了与标准的TIFF格式区分),使得原来的TIFF IFD链表结构变成了树形结构 。
图 EXIF IFD的树形结构
EXIF自定义IFD在IFD0中以DE Tag的方式出现,都是LONG类型,它记录了相应扩展IFD的起始位置(从TIFF Header开始的偏移)。
EXIF自定义标签编号的含义
TagID | 属性名称 | type | 说明 |
8769 | EXIF IFD | LONG | 数字相机的信息 |
8825 | GPS IFD | LONG | 地理位置信息 |
A005 | Interoperability IFD | LONG | 互操作扩展信息 |
927C | MakerNote IFD | LONG | 厂商自己独有的注释信息 |
扩展IFD中用到的Tag全部是EXIF重新定义的。 Tag的种类和数量非常之大,在EXIF规范里定义了各个Tag的支持级别,光是JPEG格式下必须支持的Tag就有十几个,再加上可选支持的Tag,有几十上百个,并且还存在未来继续扩充的可能。
只存在于结果由于程序一直出现catch不了的异常,
java.lang.ClassNotFoundException : com.adobe.xmp.XMPException
Well you are returning a null, are you making provision for that? – Ruan May 14 '15 at 6:19 | |
Yes i handling situation when null is being returned ! – Neeraj Jain May 14 '15 at 6:24 | |
This happened because xmpcore.jar is not in the classpath, a dependency of metadata-extractor. – saurabheights Mar 10 at 13:09 |
|
metadata-extractor依赖于xmpcore.jar 找了2天吧(我逝去的青春)
com.drewnoakes/metadata-extractor/2.8.1 依赖的jar包
GroupId | ArtifactId | Version | Scope | 描述 |
compile | The XMP Library for Java is based on the C++ XMPCore library and the API is similar. | |||
test | JUnit is a regression testing framework written by Erich Gamma and Kent Beck. It is used by the developer who implements unit tests in Java. |