exif信息是如何编码的?

Ste*_*eve 8 java exif image-processing

问候,

我将使用android从一些图像中获取exif信息.我知道有一些标准的java lib可以用在设备上.我相信我最终会使用一个.

但与此同时,有人可以向我解释这些信息是如何在JPG中编码的吗?您通常在何处/如何从文档中获取信息.当我打开他用文本编辑器记录它的所有二进制文件时.

好奇它是如何工作的以及我如何潜在地阅读有问题的数据.

Dre*_*kes 12

我参加派对有点晚了,但是为了处理Exif(以及其他类型的元数据)而编写了一个Java库,我以为我会参与其中.

EXIF

Exif基于TIFF(标记图像文件格式)构建.所以我们首先要检查TIFF:

  • TIFF文档包含多个目录,称为IFD(图像文件目录)
  • 每个IFD包含零个或多个标签
  • IFD可以链接到零个或多个其他IFD
  • 每个标记都有一个数字ID,并包含零个或多个指定数据类型的值

将结构视为树叶上具有原始值的树.TIFF是关于其结构的自我描述,但它没有规定叶子上的值实际意味着什么.

真的可以在TIFF中存储任何类型的数据,它不会耦合到图像.

TIFF文件具有通用标头:

  • 用于字节排序的2个字节,无论是ASCII MM还是IIASCII.这将告诉您要考虑所有未来字节的顺序 - 首先是LSB或MSB.
  • 2个字节的 TIFF标记,对于Exif,这是0x002A
  • 指向第一个IFD的4个字节指针

IFD具有同样简单的结构:

  • 要跟随的标签数量为2个字节
  • 标签本身的N个字节(其中N = 12*tagCount)
  • 4个字节用于指向下一个IFD的可选指针(如果没有链接IFD,则使用零值)

标签有12个字节的简单表示:

  • 标签ID为2个字节
  • 数据类型为2个字节(int8u,int16s,float等)
  • 4个字节表示指定类型的数据值
  • 值本身为4个字节,如果它适合,否则为指向另一个可能找到数据的位置的指针 - 这可能是指向另一个IFD开头的指针

数据类型是预定义的.例如:1表示8位无符号整数,12表示64位浮点数.

所以你可以继续并按照数据文件.一些观察:

  • 您无法按顺序读取数据,因为它可以在任何地方自由链接.您必须具有随机访问权限,或者通过缓冲来合成它.
  • 你所知道的就是ID 0x1234带有4个整数的标签:{1,2,3,4}

要将TIFF解码为Exif,您需要应用定义每个IFD代表的内容的字典,以及这些IFD中每个标记ID代表的内容.

JPEG

我库的大多数用户都在处理JPEG文件.JPEG具有完全不同的结构,包括一系列片段.每个段都有一个标识符和一个字节块.Exif 位于JPEG文件的APP1(数值0xe1)段中.一旦你有了这个,你必须跳过几个前导字节(Exif\0\0)才能看到MMII那个表示TIFF格式的Exif数据的开始.

将它们与一个例子结合在一起

这是我的一个库的示例图像的二进制转储:

为了:

JPEG开始

  • FF D8 是JPEG'神奇数字'.
  • FF 标记JPEG段开始.
  • E1表示JPEG段类型(这是APP1Exif所在的位置).
  • 18 B3(6,323十进制)给出段的长度(包括大小字节),因此我们知道此JPG文件的所有Exif数据将位于接下来的6,321字节内.请注意,在JPG中,多字节值使用Motorolla排序进行编码,尽管嵌套的Exif数据可能使用Intel排序.
  • 45 78 69 66 00 00或者在ASCII中Exif\0\0是Exif前导码.APP1对于Exif来说,并不是专门研究的,所以这有区别.

TIFF/Exif开始

  • 4D 4DMM表示我们在此Exif块中有Motorolla字节顺序
  • 00 2A 是我们的标准TIFF标记,如上所述
  • 00 00 00 08是第一个IFD的偏移量(8个字节),相对于TIFF头(MM在本例中).在这种情况下,这直接指向序列中的下一个字节,尽管它不必.

IFD开始

  • 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 00EASTMAN KODAK COMPANYASCII格式

生的

相机原始文件(CR2/NEF/ORW ...)通常使用TIFF,但是它们大多使用与Exif不同的标签.这些文件中的第二对字节也将不同00 2A,表示应该应用的TIFF字典的类型.


Lou*_*nco 7

如果您搜索字符串"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
Run Code Online (Sandbox Code Playgroud)

在N 12字节记录之后,您将获得上述N条记录中使用的每个偏移量所指向的数据.您需要查找ID和类型以查看它们的含义以及它们的表示方式.

  • **"数据是4字节或更少的数据,还是数据的偏移量"**非常重要,因为大多数网站都认为它只是一个偏移量. (2认同)