Как программно создать превью (миниатюру) картинки в 1С:Предприятие 8.3?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке современных систем на платформе 1С:Предприятие часто возникает задача хранения графической информации: фотографий товаров, сканов документов, чертежей или фотоотчетов. Современные фотокамеры и смартфоны генерируют файлы высокого разрешения размером от 10 до 12 Мб и более. Если пользователи вашей базы работают локально в быстрой сети, это не вызывает проблем. Но если часть клиентов подключается через медленные каналы связи (например, мобильный интернет 3G/4G), то прямая загрузка полноразмерных картинок в списки номенклатуры приведет к катастрофическому падению скорости работы интерфейса.

Единственным правильным решением в данной ситуации является использование превью (миниатюр) изображений. Мы покажем пользователю легкую «картинку-заглушку» небольшого размера (до 50–100 Кб), а тяжелый оригинальный файл будем скачивать на клиентский компьютер только по прямому требованию (например, при клике на миниатюру). В этой статье мы подробно разберем, как реализовать этот механизм в 1С.

Решение 1. Использование встроенного объекта платформы «ОбрабатываемаяКартинка»

Начиная с версии 8.3, в платформе 1С:Предприятие появился мощный инструмент для работы с графикой — объект ОбрабатываемаяКартинка. Он позволяет изменять размеры, плотность точек (DPI), формат и другие параметры изображений непосредственно средствами платформы, без привлечения стороннего программного обеспечения.

Рассмотрим готовый программный код функции, которая принимает на вход двоичные данные исходного тяжелого изображения, анализирует его размер и возвращает сжатую копию (превью) в виде двоичных данных:


Функция ПолучитьПревьюКартинки(ДанныеКартинки) Экспорт
    
    // Инициализируем объект Картинка на основании переданных двоичных данных
    Картинка = Новый Картинка(ДанныеКартинки, Истина);
    Размер = ДанныеКартинки.Размер();
    
    // Превью делаем, только если размер исходной картинки превышает 300 Кб
    МаксимальныйРазмер = 1024 * 300;  
    
    Если Размер > МаксимальныйРазмер Тогда
        
        ОбрабатываемаяКартинка = Новый ОбрабатываемаяКартинка(Картинка);
        
        // 1. Оптимизируем разрешение (DPI) для отображения на экранах
        Попытка
            Если Картинка.ПлотностьПоВертикали() >= 150 Тогда
                // Стандартное экранное разрешение — 72 или 96 DPI. Это существенно снизит вес файла.
                ОбрабатываемаяКартинка.УстановитьПлотность(72, 72);
            КонецЕсли; 
        Исключение
            // Исключение обрабатываем на случай, если формат файла не поддерживает чтение плотности точек
        КонецПопытки;
        
        // 2. Пропорционально уменьшаем геометрические размеры (ширину и высоту)
        Ширина = Картинка.Ширина();
        МаксимальнаяШирина = 150; // Целевая ширина нашей миниатюры в пикселях
        
        Если Ширина > МаксимальнаяШирина Тогда
            // Рассчитываем новую высоту с сохранением пропорций (коэффициента сжатия)
            НоваяВысота = Окр(Картинка.Высота() / Ширина * МаксимальнаяШирина);
            ОбрабатываемаяКартинка.УстановитьРазмер(МаксимальнаяШирина, НоваяВысота);
        КонецЕсли; 
        
        // Получаем измененную картинку обратно
        Картинка = ОбрабатываемаяКартинка.ПолучитьКартинку();
        
    КонецЕсли; 
    
    Возврат Картинка.ПолучитьДвоичныеДанные();
    
КонецФункции

Разберем этот алгоритм по шагам. Сначала мы проверяем размер исходного файла. Если картинка изначально весит меньше 300 Кб, то тратить ресурсы сервера на ее повторное сжатие не имеет практического смысла — мы возвращаем исходные данные. Если же картинка большая, мы передаем ее в конструктор объекта ОбрабатываемаяКартинка. Далее мы принудительно уменьшаем плотность пикселей до стандартных экранных 72 DPI и пропорционально масштабируем ширину до 150 пикселей. На выходе получаем легкую миниатюру.

Важные архитектурные рекомендации при работе с изображениями

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

  1. Никогда не сжимайте картинки «на лету» в момент открытия форм. Операция изменения размера графики требует значительных вычислительных мощностей центрального процессора сервера. Если 10 пользователей одновременно откроют динамический список товаров с картинками, сжимаемыми «на лету», рабочий процесс сервера rphost будет полностью парализован.
  2. Генерируйте превью асинхронно или в фоновом режиме. Оптимальный сценарий: пользователь прикрепляет тяжелую фотографию к номенклатуре. В этот момент система записывает оригинал файла, а задачу генерации превью передает фоновому заданию через метод ФоновыеЗадания.Выполнить(). Для пользователя процесс загрузки завершается мгновенно, а сервер в фоновом режиме за доли секунды создает миниатюру.
  3. Разделяйте хранение оригиналов и миниатюр. Рекомендуется хранить тяжелые оригиналы файлов вне информационной базы 1С — например, в томах на диске (в сетевой папке). Это позволит держать базу данных компактной. В то же время легкие превью (размером 10–30 Кб) можно хранить непосредственно в базе данных в специальном регистре сведений или реквизите справочника с типом ХранилищеЗначения. Благодаря этому динамические списки будут открываться мгновенно.

Ограничения встроенного метода платформы

Хотя объект ОбрабатываемаяКартинка является штатным и предпочтительным средством, необходимо учитывать особенности его работы:

Если сервер 1С:Предприятия работает под управлением операционной системы Linux (особенно в минимальной конфигурации без установленного графического окружения / headless-режиме), выполнение кода работы с картинками может вызывать системные ошибки. Платформа 1С для рендеринга графики использует системные библиотеки ОС. Чтобы избежать ошибок на Linux-сервере, убедитесь, что в операционной системе установлены пакеты поддержки шрифтов и работы с графикой (например, libgdiplus, fontconfig, freetype и др.).

Альтернативные способы изменения размера картинок

Если по какой-то причине стандартный метод 1С вам не подходит (например, при работе на старых версиях платформы или специфических настройках серверов), можно использовать альтернативные подходы.

Вариант А. Использование системной библиотеки Windows — WIA (Windows Image Acquisition)

Если ваш сервер приложений работает под управлением ОС 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(ПутьКФайлуПревью);

Вариант Б. Использование консольной утилиты ImageMagick

Для кроссплатформенных серверов (работающих как на Windows, так и на Linux) отличным решением является вызов внешней консольной утилиты ImageMagick. Она работает быстрее встроенных механизмов 1С и поддерживает любые графические форматы.

Разберем этот вариант подробнее. Из кода 1С с помощью функции ЗапуститьПриложение() вызывается системная команда:

convert "исходный_файл.jpg" -resize 150x150 "файл_превью.jpg"

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

Вариант В. Использование механизмов БСП (Библиотека стандартных подсистем)

Если ваша конфигурация разработана на основе БСП (что справедливо для большинства типовых конфигураций 1С, таких как ERP, Управление торговлей, Комплексная автоматизация, Бухгалтерия предприятия), вам не нужно изобретать велосипед. В составе БСП уже есть готовая подсистема «Работа с файлами». В ее программном интерфейсе присутствуют готовые экспортные методы для работы с картинками, автоматического создания их превью в фоновых заданиях и оптимального кэширования на сервере и клиенте.

Резюмируя: для создания быстрой и отзывчивой системы при работе с медиафайлами всегда разделяйте тяжелый оригинал и легкое превью. Для разработки используйте встроенный объект ОбрабатываемаяКартинка в связке с фоновыми заданиями, что гарантирует стабильную производительность вашей базы данных 1С.

← На главную