本文主要是介绍Java读取图片中的地理坐标(四),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
从图片获取信息必须要有Exif字段信息,而Exif只存在于jpeg和tiff格式中
jpeg:开头 FF D8 FF E1
(jpeg) (exif)
tif: 开头 49 49 2A 00
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文件结构类似下面这样:
JPEG SOI : FF D8 // 图片起始 JPEG APP1: FF E1 APP1 Size : 1C 45 // 注意:前面这三个WORD都是big endian的 EXIF Flag : 'Exif', 0, 0 --------- TIFF : TIFF Header: Byte Order: 'II' Flag : 2A 00 IFD0 offset : 08 00 00 00 ---------------------------- IFD0: Entries Count : 0B 00 // 11 DE 1: Tag : 0E 01 // Image Description 图像说明 Type : 02 00 // ASCII Size : 0B 00 00 00 Value : 92 00 00 00 // from TIFF Header DE 2: Tag : 0F 01 // Make 制造 Type : 02 00 Size : 06 00 00 00 Value: B2 00 00 00 DE 3: Tag : 10 01 // Model 型号 Type : 02 00 Size : 05 00 00 00 Value: CA 00 00 00 … DE 11: Tag : 69 87 // EXIF IFD Type : 04 00 // LONG Size : 01 00 00 00 Value: 1C 01 00 00 // Offset of EXIF IFD IFD1 Offset : 18 03 00 00 // END of IFD0 IFD0 DATA: ... // 存放IFD0中DE 的Value数据 EXIF sub IFD : Entries Count : 18 00 DE : Tag : 9A 82 // Exposure time ... Next IFD : 00 00 00 00 // END of EXIF IFD. 按标准IFD规定,表示没有后继IFD EXIF sub IFD Data : ... // 存放EXIF sub IFD的Value数据 ----------------------------------------------- IFD1 : // EXIF中用于存放缩略图 Entries Count : 06 00 DE : Tag : 03 01 ... Next IFD : 00 00 00 00 // END OF IFD1. EXIF只用到两个TIFF IFD IFD1 Data : ... // Thumbnail etc. ----------------------------------- // end of TIFF ----------------------------- // 其它JPEG Marker segments JPEG EOI : FF D9 // 图片结束 |
我们可以简化一下,看一个只包含主要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 |
com.drewnoakes/metadata-extractor/2.8.1 依赖的jar包
GroupId | ArtifactId | Version | Scope | 描述 |
---|---|---|---|---|
com.adobe.xmp | xmpcore | 5.1.2 | compile | The XMP Library for Java is based on the C++ XMPCore library and the API is similar. |
junit | junit | 4.11 | 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. |
这篇关于Java读取图片中的地理坐标(四)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!