Я немного опоздал на вечеринку, но, написав библиотеку 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.
Собираем все вместе с примером
Вот двоичный дамп одного из примеров изображений моей библиотеки :
В заказе:
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, который следует применять.