Быстрый (но тернистый) путь к метаданным картинок в 1С

Публикация № 1224576

Разработка - Конфигурирование 1С - Структура метаданных

EXIF GPS метаданные

Задача звучала так: прочитать GPS-геометки из картинок. Всё закончилось бы как у всех, кто брался за эту задачу, – сторонним сервисом или утилитой. Но в обсуждении кто-то сказал, «да 1С так не сможет» …

Зачем мне вообще эти метаданные?

Скажу сразу, это – скорее техническая статья про двоичные данные. Однако, чтобы люди с прикладным мышлением не обошли её стороной, опишу чем технология полезна, и какую ценность (надеюсь) добавляет моя работа. Если технические тонкости вам не интересны – после прочтения этого раздела смело переходите к последнему.

Итак, метаданные картинок нужны:

  • Продуктовому аналитику, как источник ценной продуктовой информации: модель и марка телефона, геолокация и даты снимка и многое другое – полезные данные для сегментации рынка и других маркетинговых изысканий.
  • Менеджеру, как источник фактической информации. Нередко работники, например курьеры, подтверждают выполнение задач фотографиями. Анализ геометок и даты снимка позволяют автоматизировать контроль.
  • Специалисту по антифроду – помимо упомянутых геометок и дат, метаданные оставляют много других следов: была ли фотография отредактирована и когда, в какой программе было произведено редактирование, есть ли логическое несоответствие во внутренних timestamp’ах и прочее.
  • Разработчику веб-сервисов на 1С – полезным будет оперирование файлом без сохранения на диск. Оперируя потоком можно отсекать логикой сервиса (например) картинки слишком маленького размера, черно-белые снимки, пустые архивы, аудиофайлы длины меньшей чем положено и т.д. Вас ограничивает только фантазия и соответствующий стандарт метаданных.
  • Разработчику интерфейсов – метаданные это, пожалуй, единственный быстрый способ определить ориентацию картинки -- где «верх», а где «низ» -- чтобы оператору не требовалось вертеть головой как сыч

Метаданные можно менять, их может не быть, они могут быть сфальсифицированы – и это может добавить проблем. Насколько это будет полезно именно Вам – судите сами.

Моя работа тут состоит из двух частей. Во-первых, это описание моего опыта разработки и прикладного использования, которые надеюсь, должны быть интересны сообществу. Во-вторых, это презентация обработки для чтения метаданных, которую можно использовать в своих целях. Исходный код открыт (Apache 2.0). Я надеюсь, что решение будет развиваться в рамках opensource-проекта. Пожалуйста, ставьте звезды на infostart и в github.

Как это ваще блин устроено?

Как известно, GPS-метки хранятся в файле картинки JPEG в особой секции двоичных данных – EXIF.

Решение всегда было на поверхности, с момента, когда в 8.3.9 появились объекты для работы с двоичными данными. Однако чтение EXIF - низкоуровневая задача, которая требует погружения в скучные технические нюансы и утомительного всматривания в HEX-коды. Существующие публикации на эту тему используют сторонние технологии, которые делают всю «грязную работу».

Есть энтузиасты, которые в рамках закрытых внедрений, разрабатывали похожие решения на 1С, но в открытом доступе на момент написания статьи их нет. 

 
"чтение EXIF" <> "чтение метаданных"

Пожалуй единственным доступным релевантным источником является пример с сайта ИТС по получению размера картинки. Этот пример работает молниеносно, заставляет апологетов 1С радоваться за платформу (могёт!!), но оставляет больше вопросов чем ответов.

 
 Ознакомление с кодом

Чтобы разобраться в природе магических чисел я проследовал по ссылкам в комментариях к коду и в итоге нашел обстоятельный стандарт с примерами и другие полезных ресурсы .

Начнем разбираться.

Любой файл состоит из двоичных данных (привет, кэп!). Даже шапочного понимания достаточно, чтобы догадаться о существовании «служебных» последовательностей в файле, которые определяют формат, содержимое и другие аспекты. Двоичные данные, определяющие формат файла называются сигнатурой файла. За редким исключением, сигнатура -- это первые несколько байт файла. У наших картинок это два байта: ff d8 - в шестнадцатеричном и 255 216 – в десятичном представлении. Теперь должна быть понятна природа магических цифр – воспринимать их нужно не как значения, а как "ключевые слова". Кроме того, теперь понятно - чтобы не искать GPS картинок в файлах нерелевантного формата, достаточно проверить только сигнатуру файла.

 
 Код

Именно это полезное свойство можно использовать в своих сервисах, принимающих файлы. Можно отсекать неподходящие файлы (пустые архивы, неверный формат файла и т.п), не сохраняя их на диск.

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

Можно увидеть, что секции кодируются ключевыми маркерами и длиной. Длина указывается с учетом байтов, кодирующих длину, т.е. например первая секция в файле (ffe0) занимает 16 (00 10) байт, включая сами байты 00 10.

Размеры изображения* можно прочитать из секции SOF0 (ffc0). Собственно, это и происходит в волшебном коде с сайта ИТС (192 – это c0). Далее в секции мы читаем её размер (00 11), 1-байтовое количество бит на пиксель (08), 2-байтовые ширину и высоту рисунка (00 01 и 00 02, т.е. мы имеем дело с рисунком 1x2 пикселя), и другую информацию (см. описание формата)

 
Для въедливых

Отдельные секции, как например EXIF, который нам интересен – кодируются по-особому.

Чтобы найти EXIF, нужно найти шестнадцатеричные байты: 45 78 69 66 00 00 (в примере на рисунке этой секции нет)позиция этих байтов будет нужна как реперная точка (назову её landmark), от которой мы в дальнейшем будем отсчитывать смещения. Дело в том, что секция EXIF, это по сути таблица, каждая строка в которой не может быть больше 12 байт. В таблице 4 колонки – Тег (2 байта), Тип тега (2 байта), Количество значений (4 байта) и Значение/Смещение (4 байта). Если значение умещается в 4 байта – то оно записывается непосредственно по месту, в противном случае по месту записывается сколько байтов нужно отсчитать от позиции landmark, чтобы найти нужное значение (или значения, если их несколько).

 
 Для въедливых

Другая особенность секции EXIF в том, что значения в этой секции могут кодироваться разным образом: little-endian и big-endian форматом, которые отличаются порядком чтения байтов в наборе. Формат задается следующим байтом сразу после EXIF.

Третья забавная особенность в том, что сразу после порядка байтов должно быть записано число 42. Просто потому что «ну вот так вот».

Затем задается размер смещения в байтах, которое нужно будет добавить к позиции landmark, чтобы найти записи этой таблицы EXIF. Поэтому критично, чтобы порядок следования байтов был прочитан корректно.

В следующих двух байтах хранится количество записей в таблице.

Четвертая особенность «таблицы» EXIF в том, что она иерархическая. Отдельные записи этой таблицы указывают не на значения, а на другие таблицы (каталоги) такой же структуры. Например, все значения GPS-информации записаны в отдельном «каталоге». Это позволяет использовать значения тегов более одного раза. Для иллюстрации тег 00 00 в контексте GPS-каталога тегов должен быть прочитан как GPS Version ID, а в контексте обычных EXIF-тегов как Interop index. В интернетах можно найти ресурсы, подробно описывающие перечень, назначение и типы данных тегов.

В любом теге форматом EXIV2 поддерживаются строго определенные типы данных. Их всего 9: Byte, Short, Long, Ratio, и их беззнаковые близнецы для кодирования чисел и отдельно стоящий ASCII для кодирования строк.

Искусственный пример. В таблице EXIF мы нашли такую запись:

a4 33 00 02 00 00 00 f9 00 00 00 78

Это означает тег “Lens Make” (a4 33), типа “ASCII” (00 02) из 249 символов (00 00 00 f9) расположен по адресу 120 (00 00 00 78) байтов от позиции landmark. Если отступить указанное количество байтов – можно найти непосредственно 249 символов ASCII.

Ровно таким же способом кодируются и GPS-геометки. В основной таблице EXIF в очередной 12-байтной записи в первых двух байтах будет записан тег 88 25, который означает что в файле есть геоданные и, в последних четырех байтах, будет записано смещение до нужного каталога. Если перейти туда – можно будет прочитать сначала количество записей в этом каталоге, а затем такие же 12-байтовые записи.

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

00 04 00 05 00 00 00 03 00 00 00 C0

00 04 – Долгота

00 05 – Тип Ratio

00 00 00 03 – Три значения (Градусы, минуты, секунды)

00 00 00 C0 – в 192 байтах от landmark

А в 192 байтах от landmark-байта можно будет прочитать например

00 00 00 2d 00 00 00 01 00 00 00 0d 00 00 00 01 00 00 70 30 00 00 27 10

Что можно записать условно как:

00 00 00 2d / 00 00 00 01; 00 00 00 0d / 00 00 00 01; 00 00 70 30 / 00 00 27 10

Что равно:

45 / 1; 13 / 1; 28720 / 10000

Что означает:

45 градусов 13 минут 2.872 секунды, вуаля. Мы прочитали GPS-метку!

Open source

Всё вышеописанное реализовано в виде внешней обработки

 
 Как использовать

Хотя чтение EXIF возможно и на клиенте, существующий код в данный момент серверный, потому что в моем случае файлы лежат на сервере вместе с 1С. Клиентская версия кода, если потребуется, может появиться в ходе открытой разработки. Присоединяйтесь, если вы разработчик и вам интересно.

Если вы пользовались обработкой, но что-то пошло не так – оставляйте отзывы, а лучше сразу issue на github. 

Обработка в данный момент не является законченным решением, поэтому я не предлагаю никаких подходов ни к тому как хранить, ни к тому как представлять прочитанные значения. В production-коде работает немного более продвинутая версия, заточенная под конкретные нужды.

Я ожидаю, что сообщество внесет что-то новое в функционал этой обработки, или каждый адаптирует решение для своих нужд. Критика приветствуется, но звезды в гитхаб категорически приветствуются.

Быстрый путь к метаданным

С самого начала было очевидно, что чтение должно быть довольно шустрым. И хотя полноценный бенчмарк только назревает, первое боевое использование оказалось весьма конкурентным. Случайный файл с hdd 7200 диска анализируется за 20-40 мс в «холодном» режиме, и около 10 мс в «горячем». Характерное время для хардкорных утилит – несколько миллисекунд.

Тут надо оговориться – что, время чтения сильно зависит от содержимого, и некоторые файлы могут читаться несколько секунд, даже на exiftool. И справедливо ожидать, что пакетное чтение на большом объёме в 1С может значительно уступать скомпилированным библиотекам, но порядок цифр пока радует.

Скачать файлы

Наименование Файл Версия Размер
Демонстрация чтения EXIF из JPEG

.epf 25,19Kb
3
.epf 25,19Kb 3 Скачать

Специальные предложения

Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. mixsture 16.04.20 16:34 Сейчас в теме
Круто, хардкорно! Но все равно остается вопрос: почему не взяли стороннюю утилиту? Например, тот же WIA (если клиент или сервер на win) даст сразу возможности и метки читать, и разрешения менять и много чего еще. Причем строчек в 10 кода.
3. утюгчеловек 29 16.04.20 17:31 Сейчас в теме
Мы с коллегами сначала почти так и сделали. Прельстила перспектива внести решение в ландшафт 1С плюс разобраться самому - убил двух зайцев)
В идеале хотелось бы докрутить эту обработку на чтение/редактирование. Чтобы в конфигураторе в 10 строчек кода всё красиво получалось.
2. VKislitsin 16.04.20 17:18 Сейчас в теме
На мой взгляд, отличная демонстрация возможностей работы с двоичными данными. И не абстрактно, а на примере практической задачи.
Удивительно, что плюсов совсем мало...
А за доказательство что "да 1С так сможет!" я бы и еще пару-тройку плюсов поставил - жаль не получается.
утюгчеловек; +1 Ответить
4. утюгчеловек 29 16.04.20 17:40 Сейчас в теме
(2) Двоичные данные в целом - пугают. Из-за этого мало плюсов, я думаю
Есть интуитивное ощущение, что инструменты работы с двоичными данными сильно недооценены сообществом. Еще с 8.3.9 думал, что "ну, сейчас начнется...", но пока мало хороших публикаций.
Мне вот эта нравится: https://infostart.ru/public/1061803/
5. RomanCrow13 100 04.12.20 07:29 Сейчас в теме
Статья очень интересная!
Формат jpeg не изучал, да и в принципе препарация двоичных данных в 1С не требовалась.
Предположу, что, если в файле содержится таблица с адресами пикселей и соответствующим цветом (хотя jpeg это же сжатый формат, как-то это нужно тоже учесть), то можно на чистом 1С на вход получить ДД, и вывести в соответствии с этой таблицей само изображение.
6. утюгчеловек 29 04.12.20 13:16 Сейчас в теме
(5) Грубо говоря так и есть, но не для jpeg, как ты правильно заметил, а для png
Оставьте свое сообщение

См. также

Навигатор по конфигурации базы 1С 8.3 Промо

Структура метаданных Универсальные обработки v8 v8::УФ 1cv8.cf Россия Абонемент ($m)

Универсальная внешняя обработка для просмотра метаданных конфигураций баз 1С 8.3. Отображает свойства и реквизиты объектов конфигурации, их количество, основные права доступа и т.д. Отображаемые характеристики объектов: свойства, реквизиты, стандартные рекизиты, реквизиты табличных частей, предопределенные данные, регистраторы для регистров, движения для документов, команды, чужие команды, подписки на события, подсистемы. Отображает структуру хранения объектов базы данных, для регистров доступен сервис "Управление итогами". Платформа 8.3, управляемые формы. Версия 1.1.0.75 от 15.01.2021

3 стартмани

28.10.2018    37399    334    ROL32    72    

Регламентное формирование View Таблиц SQL по дереву метаданных

Структура метаданных v8 1cv8.cf Абонемент ($m)

По выбранным метаданным формирует команды на формирование Представлений (View) Скулю и пересоздает таблицы. Работает по расписанию. Отправляет логи в SLACK.

2 стартмани

08.10.2020    1086    0    sergey279    4    

История данных (Версионирование данных). Обычные и управляемые формы. Механизм платформы 1С

Журнал регистрации Структура метаданных Расширения v8 v8::УФ 1cv8.cf Абонемент ($m)

История данных - специальный механизм платформы 1С, который позволяет хранить в базе данных данные объектов конфигурации.

1 стартмани

30.09.2020    2522    20    yuryshestakov    0    

Просмотр структуры базы в СУБД, в том числе расширений

Структура метаданных Расширения Прочие инструменты разработчика v8 1cv8.cf Абонемент ($m)

Структура таблиц базы данных с учётом расширений.

1 стартмани

29.09.2020    4489    44    Yashazz    8    

Экспорт метаданных в табличный документ

Техническое задание Структура метаданных v8 1cv8.cf Абонемент ($m)

Простая обработка позволяет выгрузить структуру хранения данных из метаданных конфигурации в табличный документ и сохранить его в файл Excel (в обычном и управляемом режимах). Выгрузка включает справочники, документы, перечисления, регистры, константы, планы, бизнес-процессы; включая табличные части и общие реквизиты; включая описания типов, в т.ч. составных, в частности, СправочникСсылка, ЛюбаяСсылка и т.п.

1 стартмани

10.08.2020    1728    8    almedv    2    

Соответствие структуры базы данных с SQL таблицами

Структура метаданных v8 v8::УФ 1cv8.cf Россия Абонемент ($m)

Данная обработка выводит соответствие структуры базы данных с SQL таблицами в режиме управляемого приложения.

1 стартмани

22.06.2020    2457    24    user1425179    1    

Просмотр данных объекта

Структура метаданных Универсальные обработки v8 v8::УФ 1cv8.cf Абонемент ($m)

Просмотр данных объектов ссылочного типа: элементов справочников, документов, бизнес-процессов, задач.

1 стартмани

18.02.2020    2694    2    armeec    1    

Инструментарий для анализа и редактирования регистров 1С (Управляемые формы)

Структура метаданных Прочие инструменты разработчика Механизмы бухгалтерского учета Механизмы оперативного учета Расчетные механизмы v8::УФ 1cv8.cf Абонемент ($m)

Набор инструментов для анализа и манипулирования записями регистров накопления, сведений, бухгалтерии и расчёта. Обладает широким спектром возможностей для отбора и редактирования. Для тех, кто работает с ЕРП.

2 стартмани

17.12.2019    8043    70    Азбука Морзе    29    

Сравнение структуры метаданных неограниченного числа конфигураций

Структура метаданных v8::УФ 1cv8.cf Абонемент ($m)

Опять слетела часть галочек в подписке на событие при сравнении/объединении с новым типовым релизом? Потеряли новый документ регистратор при переносе в продакшн?

1 стартмани

13.12.2019    2925    10    An-Aleksey    2    

Работа с базами данных 1С в SQL Server Management Studio (Расширение для SSMS)

Администрирование СУБД Производительность и оптимизация (HighLoad) Администрирование данных 1С Структура метаданных v8 Абонемент ($m)

Расширение позволяет просматривать связи объектов метаданных и таблиц БД, сгруппированные данные (по группам метаданных) об используемом дисковом пространстве и выполнять трансляцию SQL текста запроса в термины 1С. И бонусом - при наведении курсора мыши на таблицу или поле показывает назначение объекта в терминах 1С.

10 стартмани

27.11.2019    13705    43    akpaevj    46    

Расширим общую форму "Расширения", чтобы по метаданным расширения полнее понять, для чего это расширение

БСП (Библиотека стандартных подсистем) Структура метаданных Расширения v8 1cv8.cf Абонемент ($m)

Показывает метаданные расширения в общей форме БСП "Расширения" В конфигурации должна быть БСП. Версия платформы должна быть не меньше 8.3.13 Режим совместимости текущего расширения: 8.3.12 Для работы расширения безопасный режим должен быть отключен.

1 стартмани

07.11.2019    6874    3    K_A_O    0    

Карта метаданных 1С для редактора yED, для любых конфигураций

Структура метаданных Работа с интерфейсом v8 v8::УФ 1cv8.cf Россия Абонемент ($m)

Обработка "Карта метаданных 1С для редактора yED". Для отображения метаданных любых конфигураций

1 стартмани

28.10.2019    7864    17    ManyakRus    9    

Оценка заполненности базы

Инструментарий разработчика Структура метаданных v8 1cv8.cf Россия Абонемент ($m)

Количество записей в базе. Просмотр списков метаданных

1 стартмани

22.10.2019    3025    0    XACHAPURIN    2    

Вывод структуры метаданных в файл

Структура метаданных v8 v8::УФ 1cv8.cf Абонемент ($m)

Очередная вариация на тему вывода структуры базы. Выводит выбранные метаданные - Имя, синоним и тип данных в текстовый документ со структурой под формат CSV.

1 стартмани

14.03.2019    6396    18    de0nis    0