java 图像坐标是整数_Java读取图片中的地理坐标(四)

本文详细介绍了如何使用Java读取JPEG图片中的EXIF信息,特别是地理坐标。内容涉及JPEG文件结构、APP1标记、EXIF数据的位置以及TIFF IFD的链表结构,讲解了如何解析EXIF中的IFD和获取地理坐标。
摘要由CSDN通过智能技术生成

Java读取图片中的地理坐标(四)

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如图:

31d3e7bfe94f31250a59725075c5d057.png

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,则表示已经到了链表的末尾。

e1c21d4b3002487f8461583fbd330151.png

图 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链表结构变成了树形结构。

759ad95f557b79ecf20db30b4e528be9.png

图  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

描述

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读取图片中的地理坐标(四)相关教程

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值