我建议你阅读Exif 规格(PDF);它很清楚并且很容易遵循。作为一个简短的入门知识,这里是一个总结article我写:
JPEG/Exif 文件以图像标记 (SOI) 开头。 SOI 由两个魔术字节组成0xFF 0xD8
,将文件识别为 JPEG 文件。 SOI 之后有许多应用程序标记部分(APP0、APP1、APP2、APP3...),通常包括元数据。
应用标记部分
每个 APPn 部分都以一个标记开始。对于 APP0 部分,标记为0xFF 0xE0
,对于 APP1 部分0xFF 0xE1
, 等等。标记字节后面跟着两个字节,表示该部分的大小(不包括标记,包括大小字节)。长度字段后面是可变大小的应用程序数据。 APPn 部分是连续的,因此您可以跳过整个部分(通过使用部分大小),直到到达您感兴趣的部分。APPn 部分的内容有所不同,以下是 Exif APP1 部分only.
Exif APP1 部分
Exif 元数据存储在anAPP1 部分(可能有多个 APP1 部分)。 Exif APP1 部分中的应用程序数据由 Exif 标记组成0x45 0x78 0x69 0x66 0x00 0x00
("Exif\0\0"
)、TIFF 标头和许多图像文件目录 (IFD) 部分。
TIFF 标头
TIFF 标头包含有关 IFD 部分的字节顺序的信息以及指向第 0 个 IFD 的指针。前两个字节是0x49 0x49
(II
对于英特尔)如果字节顺序是小尾数或0x4D 0x4D
(MM
对于摩托罗拉)用于大端。接下来的两个字节是魔术字节0x00 0x2A
(42
;))。接下来的四个重要字节将告诉您从 TIFF 标头开始处到第 0 个 IFD 的偏移量。
重要的:JPEG 文件本身(您到目前为止一直在阅读的文件)将始终采用大端格式。但是,IFD小节的字节顺序可能不同,需要转换(您可以从上面的TIFF头中知道字节顺序)。
图像文件目录
一旦到达这里,您就可以将指针指向第 0 个 IFD 部分,并且准备好读取实际的元数据。其余的 IFD 在不同的地方被引用。 Exif IFD 和 GPS IFD 的偏移量在第 0 个 IFD 字段中给出。第 0 个 IFD 字段后给出第一个 IFD 的偏移量。 Exif IFD 中给出了互操作性 IFD 的偏移量。
IFD 只是元数据字段的连续记录。字段计数在 IFD 的前两个字节中给出。字段计数后面是 12 字节字段。在这些字段之后,有一个从 TIFF 标头的开头到第一个 IFD 的开头的 4 字节偏移量。该值仅对第 0 个 IFD 有意义。接下来是 IFD 数据部分。
IFD 字段
字段是 IFD 部分的 12 字节子部分。每个字段的前两个字节给出 Exif 标准中定义的标签 ID。接下来的两个字节给出了字段数据的类型。你将会拥有1
for byte
, 2
for ascii
, 3
for short
(uint16
), 4
for long
(uint32
)等。查看 Exif 规范以获取完整列表。
接下来的四个字节可能有点令人困惑。对于字节数组 (ascii
and undefined types
),给出了数组的字节长度。例如,对于 Ascii 字符串:"Exif"
,计数将为 5(包括空终止符)。对于其他类型,这是场分量的数量(例如 4 个空头,3 个有理数)。
计数之后,我们得到 4 字节字段值。然而,如果字段数据的长度超过4个字节,它将被存储在IFD数据部分。在这种情况下,该值将是从 TIFF 标头的开头到字段数据的开头的偏移量。例如,对于一个long
(uint32
,4 个字节),这将是字段值。为一个rational
(2 x uint32
, 8 字节),这将是 8 字节字段数据的偏移量。
这基本上就是 JPEG/Exif 文件中元数据的排列方式。有一些注意事项需要记住(记住根据需要转换字节顺序,偏移量是从 TIFF 标头的开头开始,跳转到数据部分以读取长字段,...),但格式非常容易阅读。以下是 JPEG/Exif 文件的颜色编码十六进制视图。蓝色块代表 SOI,橙色块代表 TIFF 标头,绿色块代表 IFD 大小和偏移字节,浅紫色块代表 IFD 字段,深紫色块代表字段数据。