Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java exif信息是如何编码的?_Java_Image Processing_Exif - Fatal编程技术网

Java exif信息是如何编码的?

Java exif信息是如何编码的?,java,image-processing,exif,Java,Image Processing,Exif,您好 我将使用android从一些图像中获取exif信息。我知道有一些标准的java库,我可以在设备上使用。我相信我最终会使用一个 但与此同时,有人能向我解释一下这些信息是如何在JPG中编码的吗?您通常在哪里/如何从文档中获取信息。当我用文本编辑器打开文档时,它是全二进制的 我很好奇它是如何工作的,以及我如何可能读取有问题的数据。有一些关于EXIF数据在文件中存储的方式和位置的指针。当然,总有它自己需要阅读。如果你搜索字符串“Exif”,你会找到Exif数据的开头——这相当复杂,我建议使用库——

您好

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

但与此同时,有人能向我解释一下这些信息是如何在JPG中编码的吗?您通常在哪里/如何从文档中获取信息。当我用文本编辑器打开文档时,它是全二进制的


我很好奇它是如何工作的,以及我如何可能读取有问题的数据。

有一些关于EXIF数据在文件中存储的方式和位置的指针。当然,总有它自己需要阅读。

如果你搜索字符串“Exif”,你会找到Exif数据的开头——这相当复杂,我建议使用库——(例如,如果你使用的是.NET,我公司的)

下面是一个高层描述:

Exif本身位于AppMarker内部——前面的三个字节将是E1(AppMarker 1),并且标记数据的大小与文件的结尾一致。Exif后两个字节,您将看到endianness标记(例如,
49
表示
II
,表示英特尔,小endian——这意味着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是


这是Java和EXIF的好库之一:

我来晚了一点,但是写了一个(在其他类型的元数据中)我想我会加入进来

图像信息 Exif基于TIFF,即标记图像文件格式。因此,我们首先要检查TIFF:

  • TIFF文档包含多个称为IFD(图像文件目录)的目录
  • 每个IFD包含零个或多个标记
  • IFD可以链接到零个或多个其他IFD
  • 每个标记都有一个数字ID,并且包含零个或多个指定数据类型的值
将该结构视为一棵在叶子处具有原始值的树。TIFF是对其结构的自我描述,但它没有规定叶子上的值的实际含义

实际上,您可以在TIFF中存储任何类型的数据,它不与图像耦合

TIFF文件有一个通用头:

  • 2个字节用于字节排序,ASCII中的
    MM
    II
    。这将告诉您在LLSB或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
),然后才能看到表示TIFF格式Exif数据开始的
MM
II

用一个例子把所有这些结合起来 这是我的一个库的二进制转储:

为了:

JPEG开始了
  • FF D8
    是JPEG的“幻数”
  • FF
    标记JPEG段的开始
  • E1
    表示JPEG段类型(这是Exif所在的
    APP1
  • 18 B3
    (6323十进制)给出了段的长度(包括大小字节),因此我们知道此JPG文件的所有Exif数据将位于接下来的6321字节内。请注意,在JPG中,多字节值使用Motorolla排序进行编码,尽管嵌套的Exif数据可能使用Intel排序
  • 45 78 69 66 00 00
    或ASCII
    Exif\0\0
    中的Exif前导码
    APP1
    并不是专门为Exif重新保存的,因此这是有区别的
TIFF/Exif启动
  • 4D 4D
    MM
    表示我们在此Exif块中有Motorolla字节顺序
  • 00