问候,
我将使用 android 从一些图像中获取 exif 信息。我知道有一些标准的 java lib 可以与设备一起使用。我相信我最终会使用一个。
但与此同时,有人可以向我解释这些信息是如何在 JPG 中编码的吗?您通常在哪里/如何从文档中获取信息。当我打开他用文本编辑器记录它的所有二进制文件时。
好奇它是如何工作的,以及我如何可能读取有问题的数据。
问候,
我将使用 android 从一些图像中获取 exif 信息。我知道有一些标准的 java lib 可以与设备一起使用。我相信我最终会使用一个。
但与此同时,有人可以向我解释这些信息是如何在 JPG 中编码的吗?您通常在哪里/如何从文档中获取信息。当我打开他用文本编辑器记录它的所有二进制文件时。
好奇它是如何工作的,以及我如何可能读取有问题的数据。
我参加聚会有点晚了,但是我写了一个用于处理 Exif(以及其他类型的元数据)的 Java 库,我想我会插话的。
Exif 建立在TIFF(标记图像文件格式)之上。所以我们首先要检查 TIFF:
将结构想象成一棵在叶子上具有原始值的树。TIFF 是关于其结构的自我描述,但它并没有说明叶子上的值的实际含义。
实际上,您可以在 TIFF 中存储任何类型的数据,它不与图像耦合。
TIFF 文件有一个通用标题:
MM
要么II
是 ASCII。这告诉您以什么顺序考虑所有未来的字节——首先是 LSB 或 MSB。0x002A
IFD 具有同样简单的结构:
标签有 12 个字节的简单表示:
数据类型是预定义的。例如:1 代表 8 位无符号整数,12 代表 64 位浮点数。
因此,您可以继续关注数据文件。一些观察:
0x1234
有 4 个整数:{1,2,3,4}
要将 TIFF 解码为 Exif,您需要应用定义每个 IFD 代表什么以及这些 IFD 中的每个标签 ID 代表什么的字典。
我图书馆的大多数用户都在处理 JPEG 文件。JPEG 具有完全不同的结构,由一系列片段组成。每个段都有一个标识符和一个字节块。Exif 位于 JPEG 文件的APP1
(数值0xe1
)段中。一旦你有了它,你必须跳过几个前导字节 ( Exif\0\0
),然后才能看到表示 TIFF 格式的 Exif 数据开始的MM
or 。II
这是我图书馆的一个示例图像的二进制转储:
为了:
FF D8
是 JPEG 的“幻数”。FF
标记 JPEG 段的开始。E1
表示 JPEG 段类型(这是APP1
Exif 所在的位置)。18 B3
(十进制的 6,323)给出了段的长度(包括大小字节),所以我们知道这个 JPG 文件的所有 Exif 数据都将位于接下来的 6,321 字节内。请注意,在 JPG 中,多字节值使用 Motorolla 排序进行编码,尽管嵌套的 Exif 数据可能使用 Intel 排序。45 78 69 66 00 00
或者在 ASCIIExif\0\0
中是 Exif 序言。APP1
不是专门为 Exif 保留的,所以这是有区别的。4D 4D
或MM
表示我们在此 Exif 块中有 Motorolla 字节顺序00 2A
是我们的标准 TIFF 标记,如上所述00 00 00 08
是第一个 IFD 的偏移量(8 字节),相对于 TIFF 标头(MM
在这种情况下)。在这种情况下,它直接指向序列中的下一个字节,尽管它不是必须的。00 08
打开我们的第一个 IFD 并告诉我们将有 8 个标签出现01 0F
是第一个 IFD 中第一个标签的 ID,在这种情况下是相机的制造商00 02
是值的类型(2 表示它是一个 ASCII 字符串)00 00 00 16
是组件的数量,这意味着我们将有一个 22 字节的字符串00 00 01 B2
(十进制 434)是指向该字符串位置的指针,相对于 TIFF 标头 ( MM
)。您在此屏幕截图中看不到它,但它指向45 41 53 54 4D 41 4E 20 4B 4F 44 41 4B 20 43 4F 4D 50 41 4E 59 00
哪个是EASTMAN KODAK COMPANY
ASCII相机原始文件(CR2/NEF/ORW...)通常使用 TIFF,但它们大多使用与 Exif 不同的标签。这些文件中的第二对字节也将不同00 2A
,指示应该应用的 TIFF 字典的类型。
如果您搜索字符串“Exif”,您会发现 Exif 数据的开头——它非常复杂,我建议使用库——(例如,如果您使用的是 .NET,则使用我公司的DotImage)。
不过,这是一个高级别的描述:
Exif 本身位于 AppMarker 内部——之前的三个字节将是 E1(AppMarker 1)和文件字节序中标记数据的大小。在 Exif 之后的两个字节,您将看到字节序标记(例如,这49 49
意味着II
英特尔、小端 - 这意味着 2 字节数字在文件中具有低字节)。
其余数据广泛使用偏移量,偏移量来自第一个字节序的位置(上例中的 49)
这个偏移量的 8 个字节是一个 2 字节的数字,它是 exif 标签的数量。如果您按II
字节顺序排列,请反转字节以读取长度。
那么就会有这个数量的 12 字节的记录。每一个是:
2 bytes: Tag ID
2 bytes: Tag Type
4 bytes: Length
4 bytes: data if the data is 4 bytes or less, or an offset to the data
在 N 条 12 字节的记录之后,您将拥有上述 N 条记录中使用的每个偏移量所指向的数据。您需要查找 id 和类型以了解它们的含义以及它们的表示方式。
解析 EXIF 数据非常繁琐,但您可以找到许多库来解析它。我最喜欢的 Java 是,
http://www.java2s.com/Open-Source/Java-Document/Web-Server/Jigsaw/org/w3c/tools/jpeg/Exif.java.htm
这是 Java 和 EXIF 的优秀库之一:http ://www.drewnoakes.com/code/exif/