Как кодируется информация exif? - PullRequest
7 голосов
/ 30 ноября 2009

Привет,

Я собираюсь получить exif-информацию из некоторых изображений с помощью Android. Я знаю, что есть некоторые стандартные библиотеки Java, которые я мог бы использовать с устройством. Я уверен, что в итоге буду использовать один.

Но в то же время кто-нибудь может объяснить мне, как эта информация закодирована в JPG? Где / как вы обычно получаете информацию из документа. Когда я открываю, он документирует текстовым редактором, все в двоичном формате.

Любопытно, как это работает и как я могу потенциально прочитать данные.

Ответы [ 5 ]

10 голосов
/ 02 января 2013

Я немного опоздал на вечеринку, но, написав библиотеку Java для обработки Exif (среди других типов метаданных), я подумал, что я должен вмешаться.

Exif

Exif основан на TIFF , формате файла тегового изображения. Итак, сначала мы должны изучить TIFF:

  • Документ TIFF содержит несколько каталогов , известных как IFD (каталоги файлов изображений)
  • Каждый IFD содержит ноль или более тегов
  • IFD могут ссылаться на ноль или более других IFD
  • Каждый тег имеет числовой идентификатор и содержит ноль или более значений указанного типа данных

Думайте о структуре как о дереве с примитивными значениями на листьях. TIFF самостоятельно описывает свою структуру, но ничего не указывает на то, что значения на листьях на самом деле означают .

На самом деле вы можете хранить любые данные в формате TIFF, они не связаны с изображениями.

Файл TIFF имеет общий заголовок:

  • 2 байта для порядка следования байтов, MM или II в ASCII. Это говорит вам, в каком порядке следует учитывать все будущие байты в - LSB или MSB.
  • 2 байта маркер TIFF, для Exif это 0x002A
  • 4 байта указатель на первое IFD

IFD имеют одинаково простую структуру:

  • 2 байта для количества следующих тегов
  • N байтов для самих тегов (где N = 12 * tagCount)
  • 4 байта для необязательного указателя на следующее IFD (используйте нулевое значение, если IFD не связан)

Теги имеют простое представление в 12 байтов:

  • 2 байта для идентификатора тега
  • 2 байта для типа данных (int8u, int16s, float и т. Д.)
  • 4 байта для количества значений данных указанного типа
  • 4 байта для самого значения, если оно подходит, в противном случае для указателя на другое место, где могут быть найдены данные - это может быть указатель на начало другого IFD

Типы данных предварительно определены. Например: 1 представляет 8-разрядные целые числа без знака, а 12 представляет 64-разрядные числа с плавающей запятой.

Так что со всем, что вы можете пойти дальше и следить за файлом данных. Некоторые наблюдения:

  • Вы не можете прочитать данные по порядку, так как они могут свободно ссылаться повсюду. Вы должны либо иметь произвольный доступ, либо синтезировать его путем буферизации.
  • Все, что вы знаете на данный момент, это то, что тег с идентификатором 0x1234 имеет 4 целых числа: {1,2,3,4}

Чтобы декодировать TIFF в Exif, вам нужно применить словарь, который определяет, что представляет каждый IFD, и что представляет каждый идентификатор тега в этих IFD.

JPEG

Большинство пользователей моей библиотеки обрабатывают файлы JPEG. JPEG-файлы имеют совершенно другую структуру, состоящую из последовательности сегментов. Каждый сегмент имеет идентификатор и блок байтов. Exif находится в сегменте APP1 (числовое значение 0xe1) файла JPEG. Получив это, вы должны пропустить несколько старших байтов (Exif\0\0), прежде чем увидите MM или II, которые обозначают начало данных Exif в формате TIFF.

Собираем все вместе с примером

Вот двоичный дамп одного из примеров изображений моей библиотеки :

image

В заказе:

JPEG запускается

  • FF D8 - это «магическое число» в формате JPEG.
  • FF отмечает начало сегмента JPEG.
  • E1 указывает тип сегмента JPEG (это APP1, где живет Exif).
  • 18 B3 (6,323 десятичных) дает длину сегмента (включая байты размера), поэтому мы знаем, что все данные Exif для этого файла JPG будут находиться в следующих 6,321 байтах. Обратите внимание, что в JPG многобайтовые значения кодируются в порядке Motorolla, хотя во вложенных данных Exif может использоваться порядок Intel.
  • 45 78 69 66 00 00 или в ASCII Exif\0\0 - преамбула Exif. APP1 не распространяется исключительно на Exif, так что это различает.

TIFF / Exif начинается

  • 4D 4D или MM указывает, что у нас есть порядок байтов Motorolla в этом блоке Exif
  • 00 2A - наш стандартный маркер TIFF, как обсуждалось выше
  • 00 00 00 08 - это смещение (8 байтов) первого IFD относительно заголовка TIFF (MM в данном случае). В этом случае это указывает непосредственно на следующий байт в последовательности, хотя это не обязательно.

IFD начинается

  • 00 08 открывает наш первый IFD и сообщает, что у нас будет 8 тегов

Метка начинается

  • 01 0F - это идентификатор первого тега в первом IFD, в данном случае производитель камеры
  • 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

RAW

Файлы необработанных снимков (CR2 / NEF / ORW ...) обычно используют TIFF, однако в большинстве случаев они используют теги, отличные от тегов для Exif. Вторая пара байтов в этих файлах также будет отличаться от 00 2A, указывая на тип словаря TIFF, который следует применять.

5 голосов
/ 30 ноября 2009

Если вы ищете строку «Exif», вы найдете начало данных Exif - это довольно сложно, и я бы рекомендовал использовать библиотеку - (например, DotImage моей компании, если вы используя .NET).

Вот описание высокого уровня:

Сам Exif находится внутри AppMarker - три байта перед ним будут E1 (AppMarker 1) и размер данных маркера в порядке байтов файла. Через два байта после Exif вы увидите маркер порядка байтов (например, 49 49 означает II, что означает Intel, little 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 записях. Вам нужно посмотреть идентификаторы и типы, чтобы увидеть, что они означают и как они представлены.

3 голосов
/ 30 ноября 2009

Википедия содержит несколько указателей на то, как и где именно данные EXIF ​​хранятся в файле. Конечно, всегда есть стандарт для чтения.

1 голос
/ 30 ноября 2009

Это одна из хороших библиотек для Java и EXIF: http://www.drewnoakes.com/code/exif/

1 голос
/ 30 ноября 2009

Анализировать EXIF-данные довольно утомительно, но вы можете найти много библиотек для их анализа. Мой любимый для Java,

http://www.java2s.com/Open-Source/Java-Document/Web-Server/Jigsaw/org/w3c/tools/jpeg/Exif.java.htm

http://jigsaw.w3.org/

...