JPEG raw blob中的“元数据”边界究竟在哪里?

时间:2014-10-31 12:18:40

标签: java javascript c image jpeg

我知道有很多类型的"元数据"在JPEG图像中:

http://fotoforensics.com/tutorial-meta.php

但是我必须在哪里剪切字节数组以将blob拆分为一般元数据部分和剩余的实际图像数据部分?

我想保留所有元数据,调整图片大小,然后再次添加以前存储的元数据。

什么是神奇的分隔符字节序列或位置?

感谢

2 个答案:

答案 0 :(得分:4)

简短的回答是"这取决于......" :)

这里有几点需要考虑:

  1. 严格来说," jpeg"是实际图像数据的编码,并没有指定我认为你想要它的文件格式。常见的文件格式是JFIF或Exif,每种格式都允许不同类型的元数据
  2. JFIF和Exif文件格式在元数据和图像数据之间没有完整的硬边界。例如,JFIF文件由许多段组成;几乎所有这些都跟着一些数据。 Exif更复杂,但遵循相同的原则。例如,有几个标签定义为APP0 ... APPn。许多程序/公司使用这些段来编码某种形式的元数据。在每个段标记之后是两个字节长度的字段,然后是最多64K的数据(由长度字段的两个字节限定)。
  3. 可以使用任意数量的这些字段来指定元数据
  4. 这些字段在技术上可以出现在文件的任何位置,尽管它们通常只能在"图像数据之前找到"
  5. 术语"图像数据"非常宽松。我相信你的意思是"图像数据"实际上也分布在许多不同类型的细分市场中。举一个简单的例子,有霍夫曼编码表段(以段标记0xFFC4开头)和实际扫描数据段(以段标记0xFFDA开头)。我认为有充分理由认为这些细分市场都被认为是"图像数据"
  6. 我远不是这些格式的专家,但遗憾的是我认为答案比你希望的要复杂得多。如果要读取所有非图像数据信息,则实际上需要解析整个图像文件。好消息是,我确信必须有图书馆才能做到这一点(虽然我不了解JS库)。

    这非常过于简化,但它只是为了让您了解需要了解的内容

    -Edit-一些参考文献:

    http://en.wikibooks.org/wiki/JPEG_-_Idea_and_Practice/The_header_part

    http://en.wikipedia.org/wiki/JPEG#JPEG_files

    The actual JFIF file spec

    http://en.wikipedia.org/wiki/Exchangeable_image_file_format

    The actual Exif file spec

答案 1 :(得分:0)

我回复清理一些事情。 JPEG标准是不可实现的。例如,它定义了如何编码和解码组件,但没有定义它的组件。 JFIF是第一种常用的填充空白的JPEG文件格式。

如果我们将元数据定义为解码压缩图像所不需要的所有描述性数据;数据和元数据之间有一个相当清晰的界限。在大多数情况下,任何APPn或COM标记都是元数据。

我说大部分是因为仅仅存在JFIF APP0标记告诉解码器图像是灰度或YCbCr格式,未校正伽马。实际上JFIF中的元数据非常少(缩略图,像素密度)。

JFIF和EXIF流的结构仅在定义格式的APPn标记的格式上有所不同。由于APPn标记包括长度,因此解码器可以跳过标记而不读取任何元数据。换句话说,JPEG解码器只需要知道它遇到了JFIF APP0标记或EXIF APP1标记来解码图像,而不需要读取这些标记内的数据。

EXIF优于JFIF的复杂性仅发生在APPn标记中。同样,解码器可以通过简单地跳过标记来忽略这种复杂性。

JFIF要求流以SOI标记开始,后跟APP1 JFIF标记。之后,您可以按任何顺序包含所需的任何APPn或COM标记。唯一的限制是标记数据不能以JFIF或JFXX开头。

JFIF APP0标记中没有任何内容链接到压缩数据。 EXIF不适用。您可以在APP1标记中对图像大小进行编码,该标记也在SOF标记中编码。我不知道如果那些价值不同会发生什么。解码器可能会使用SOF标记中的值并忽略APP1标记中的值。但是,某些应用程序可能不喜欢不同的值。

标记级别的JPEG流结构非常简单。 EXIF标题过于复杂。