При разработке современных систем на платформе 1С:Предприятие часто возникает задача хранения графической информации: фотографий товаров, сканов документов, чертежей или фотоотчетов. Современные фотокамеры и смартфоны генерируют файлы высокого разрешения размером от 10 до 12 Мб и более. Если пользователи вашей базы работают локально в быстрой сети, это не вызывает проблем. Но если часть клиентов подключается через медленные каналы связи (например, мобильный интернет 3G/4G), то прямая загрузка полноразмерных картинок в списки номенклатуры приведет к катастрофическому падению скорости работы интерфейса.
Единственным правильным решением в данной ситуации является использование превью (миниатюр) изображений. Мы покажем пользователю легкую «картинку-заглушку» небольшого размера (до 50–100 Кб), а тяжелый оригинальный файл будем скачивать на клиентский компьютер только по прямому требованию (например, при клике на миниатюру). В этой статье мы подробно разберем, как реализовать этот механизм в 1С.
Начиная с версии 8.3, в платформе 1С:Предприятие появился мощный инструмент для работы с графикой — объект ОбрабатываемаяКартинка. Он позволяет изменять размеры, плотность точек (DPI), формат и другие параметры изображений непосредственно средствами платформы, без привлечения стороннего программного обеспечения.
Рассмотрим готовый программный код функции, которая принимает на вход двоичные данные исходного тяжелого изображения, анализирует его размер и возвращает сжатую копию (превью) в виде двоичных данных:
Функция ПолучитьПревьюКартинки(ДанныеКартинки) Экспорт
// Инициализируем объект Картинка на основании переданных двоичных данных
Картинка = Новый Картинка(ДанныеКартинки, Истина);
Размер = ДанныеКартинки.Размер();
// Превью делаем, только если размер исходной картинки превышает 300 Кб
МаксимальныйРазмер = 1024 * 300;
Если Размер > МаксимальныйРазмер Тогда
ОбрабатываемаяКартинка = Новый ОбрабатываемаяКартинка(Картинка);
// 1. Оптимизируем разрешение (DPI) для отображения на экранах
Попытка
Если Картинка.ПлотностьПоВертикали() >= 150 Тогда
// Стандартное экранное разрешение — 72 или 96 DPI. Это существенно снизит вес файла.
ОбрабатываемаяКартинка.УстановитьПлотность(72, 72);
КонецЕсли;
Исключение
// Исключение обрабатываем на случай, если формат файла не поддерживает чтение плотности точек
КонецПопытки;
// 2. Пропорционально уменьшаем геометрические размеры (ширину и высоту)
Ширина = Картинка.Ширина();
МаксимальнаяШирина = 150; // Целевая ширина нашей миниатюры в пикселях
Если Ширина > МаксимальнаяШирина Тогда
// Рассчитываем новую высоту с сохранением пропорций (коэффициента сжатия)
НоваяВысота = Окр(Картинка.Высота() / Ширина * МаксимальнаяШирина);
ОбрабатываемаяКартинка.УстановитьРазмер(МаксимальнаяШирина, НоваяВысота);
КонецЕсли;
// Получаем измененную картинку обратно
Картинка = ОбрабатываемаяКартинка.ПолучитьКартинку();
КонецЕсли;
Возврат Картинка.ПолучитьДвоичныеДанные();
КонецФункции
Разберем этот алгоритм по шагам. Сначала мы проверяем размер исходного файла. Если картинка изначально весит меньше 300 Кб, то тратить ресурсы сервера на ее повторное сжатие не имеет практического смысла — мы возвращаем исходные данные. Если же картинка большая, мы передаем ее в конструктор объекта ОбрабатываемаяКартинка. Далее мы принудительно уменьшаем плотность пикселей до стандартных экранных 72 DPI и пропорционально масштабируем ширину до 150 пикселей. На выходе получаем легкую миниатюру.
Просто написать функцию сжатия недостаточно для обеспечения высокой производительности системы. Проанализируем ключевые правила архитектуры хранения медиафайлов в 1С:
rphost будет полностью парализован.ФоновыеЗадания.Выполнить(). Для пользователя процесс загрузки завершается мгновенно, а сервер в фоновом режиме за доли секунды создает миниатюру.ХранилищеЗначения. Благодаря этому динамические списки будут открываться мгновенно.Хотя объект ОбрабатываемаяКартинка является штатным и предпочтительным средством, необходимо учитывать особенности его работы:
Если сервер 1С:Предприятия работает под управлением операционной системы Linux (особенно в минимальной конфигурации без установленного графического окружения / headless-режиме), выполнение кода работы с картинками может вызывать системные ошибки. Платформа 1С для рендеринга графики использует системные библиотеки ОС. Чтобы избежать ошибок на Linux-сервере, убедитесь, что в операционной системе установлены пакеты поддержки шрифтов и работы с графикой (например, libgdiplus, fontconfig, freetype и др.).
Если по какой-то причине стандартный метод 1С вам не подходит (например, при работе на старых версиях платформы или специфических настройках серверов), можно использовать альтернативные подходы.
Если ваш сервер приложений работает под управлением ОС Windows, вы можете использовать встроенную службу работы с изображениями через COM-соединение. Этот способ не требует установки стороннего софта.
Посмотрим на пример реализации изменения размера через WIA:
// Примерный алгоритм масштабирования через WIA.ImageProcess
Изображение = Новый COMОбъект("WIA.ImageFile");
Изображение.LoadFile(ПутьКИсходномуФайлу);
ФильтрМасштаба = Новый COMОбъект("WIA.ImageProcess");
ФильтрМасштаба.Filters.Add(ФильтрМасштаба.FilterInfos("Scale").FilterID);
// Задаем параметры фильтра сжатия
ФильтрМасштаба.Filters(1).Properties("MaximumWidth").Value = 150;
ФильтрМасштаба.Filters(1).Properties("MaximumHeight").Value = 150;
ФильтрМасштаба.Filters(1).Properties("PreserveAspectRatio").Value = Истина;
Изображение = ФильтрМасштаба.Apply(Изображение);
Изображение.SaveFile(ПутьКФайлуПревью);
Для кроссплатформенных серверов (работающих как на Windows, так и на Linux) отличным решением является вызов внешней консольной утилиты ImageMagick. Она работает быстрее встроенных механизмов 1С и поддерживает любые графические форматы.
Разберем этот вариант подробнее. Из кода 1С с помощью функции ЗапуститьПриложение() вызывается системная команда:
convert "исходный_файл.jpg" -resize 150x150 "файл_превью.jpg"
После успешного завершения команды созданный файл превью считывается обратно в информационную базу в виде двоичных данных.
Если ваша конфигурация разработана на основе БСП (что справедливо для большинства типовых конфигураций 1С, таких как ERP, Управление торговлей, Комплексная автоматизация, Бухгалтерия предприятия), вам не нужно изобретать велосипед. В составе БСП уже есть готовая подсистема «Работа с файлами». В ее программном интерфейсе присутствуют готовые экспортные методы для работы с картинками, автоматического создания их превью в фоновых заданиях и оптимального кэширования на сервере и клиенте.
Резюмируя: для создания быстрой и отзывчивой системы при работе с медиафайлами всегда разделяйте тяжелый оригинал и легкое превью. Для разработки используйте встроенный объект ОбрабатываемаяКартинка в связке с фоновыми заданиями, что гарантирует стабильную производительность вашей базы данных 1С.