Как изменить размер и сжать изображение в формате PNG в 1С:Предприятие?

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

При разработке прикладных решений на платформе 1С:Предприятие часто возникает задача оптимизации объема хранимых файлов. Пользователи могут загружать тяжелые изображения (логотипы товаров, схемы, фотографии номенклатуры), что приводит к быстрому росту базы данных и замедлению работы веб-клиентов. Форматы JPEG и PNG требуют принципиально разного подхода к сжатию и обработке. Рассмотрим, как правильно настроить обработку PNG-файлов с помощью внешней утилиты ImageMagick, разберем скрытые нюансы параметров сжатия, а также изучим альтернативный современный способ обработки картинок встроенными средствами 1С. Для удобной предварительной загрузки таких файлов в систему пользователями можно использовать метод добавления картинок на управляемую форму с помощью Drag & Drop.

В чем сложность работы с форматом PNG?

В отличие от формата JPEG, который использует сжатие с потерями, формат PNG является беспрецедентным стандартом сжатия графики без потерь (Lossless). Напрямую применить к нему параметры сжатия JPEG не удастся. Попытка использовать привычный параметр -quality в ImageMagick для файлов PNG работает совершенно иначе, чем для JPEG, и может привести к неожиданным результатам.

Проанализируем детально, как утилита ImageMagick интерпретирует параметр -quality для изображений PNG. Значение этого параметра состоит из двух цифр (десятков и единиц):

  1. Десятки (первая цифра от 0 до 9): определяют уровень сжатия библиотекой zlib. Значение 0 означает отсутствие сжатия (быстро, но файл будет огромным), а 9 — максимальное сжатие (требует больше процессорного времени, но дает минимальный размер).
  2. Единицы (вторая цифра от 0 до 9): определяют тип предварительного адаптивного фильтра PNG (PNG-фильтрация). Каждый фильтр по-разному подготавливает строки пикселей для последующего сжатия. Значение 5 включает наиболее эффективный адаптивный алгоритм подбора фильтров для каждой строки изображения.

Таким образом, если мы указываем параметр -quality 75 для PNG, это означает: уровень сжатия zlib равен 7, а тип фильтра равен 5. Если же мы по ошибке скопируем строку от JPEG и укажем -quality 70, мы получим уровень сжатия 7 и тип фильтра 0 (без фильтрации), что существенно ухудшит итоговый размер файла.

Вариант 1. Оптимальное сжатие PNG через ImageMagick в 1С

Для того чтобы добиться максимального сжатия PNG без потери визуального качества, рекомендуется использовать специализированные параметры фильтрации и сжатия, а также удалять метаданные (профили камер, EXIF, комментарии), которые могут занимать до половины объема исходного файла.

Выясним назначение ключевых параметров командной строки ImageMagick для PNG:

Давайте модифицируем процедуру обработки файлов на сервере 1С. Мы добавим условие, которое проверяет расширение файла и применяет индивидуальные параметры командной строки для JPEG и PNG.

Посмотрим на пример реализации такой процедуры:


&НаСервере
Процедура ОбработатьИзображенияНаСервере()
    МестоПоложение = "C:\Файлы1с\";
    Индекс = 1;
    
    Для каждого СтрТч из ИзображенияДляОбработки Цикл
        Если Не СтрТч.Обрабатывать Тогда
            Продолжить;
        КонецЕсли;
        
        ПутьКФайлу = СокрЛП(СтрТч.ПутьКФайлу);
        СтароеИмя  = МестоПоложение + ПутьКФайлу;
        
        // Определяем расширение файла для выбора алгоритма сжатия
        ФайлСведения = Новый Файл(СтароеИмя);
        Расширение = НРег(ФайлСведения.Расширение);
        
        НовоеИмяФайла = МестоПоложение + Лев(ПутьКФайлу, СтрДлина(ПутьКФайлу) - СтрДлина(Расширение)) + "new" + Расширение;
        
        // Обработка файлов размером более 5 МБ
        Если ФайлСведения.Размер() >= 5000000 Тогда
            
            СтрокаПараметров = "";
            
            Если Расширение = ".png" Тогда
                // Настройки максимального сжатия без потерь для PNG
                СтрокаПараметров = " -filter Lanczos -strip -define png:compression-filter=5 -define png:compression-level=9 -define png:compression-strategy=1 -gaussian-blur 0.05 ";
            ИначеЕсли Расширение = ".jpg" Или Расширение = ".jpeg" Тогда
                // Настройки сжатия с потерями для JPEG
                Если ФайлСведения.Размер() < 35000000 Тогда
                    СтрокаПараметров = " -filter Lanczos -define jpeg:dct-method=float -quality 75 -gaussian-blur 0.05 ";
                Иначе
                    СтрокаПараметров = " -filter Lanczos -define jpeg:dct-method=float -quality 70 -gaussian-blur 0.05 ";
                КонецЕсли;
            КонецЕсли;
            
            Если ЗначениеЗаполнено(СтрокаПараметров) Тогда
                КомандаЗапуска = """C:\Program Files\ImageMagick-7.0.10-Q16-HDRI\convert.exe"" """ + СтароеИмя + """" + СтрокаПараметров + """" + НовоеИмяФайла + """";
                
                // Запуск утилиты в синхронном режиме (ожидаем завершения обработки)
                ЗапуститьПриложение(КомандаЗапуска, , Истина);
                
                // Обновляем информацию о файле в базе данных
                НовыйСозданныйФайл = Новый Файл(НовоеИмяФайла);
                Если НовыйСозданныйФайл.Существует() Тогда
                    СпрОбъект = СтрТч.ПрисоединенныеФайлы.ПолучитьОбъект();
                    СпрОбъект.ПутьКФайлу = Лев(ПутьКФайлу, СтрДлина(ПутьКФайлу) - СтрДлина(Расширение)) + "new" + Расширение;
                    СпрОбъект.Размер     = НовыйСозданныйФайл.Размер();
                    СпрОбъект.Записать();
                    
                    // Переносим исходный тяжелый файл в архивную папку
                    ПапкаАрхива = "C:\Файлы1с\ФайлыДляУдаления\";
                    ПереместитьФайл(СтароеИмя, ПапкаАрхива + СтрТч.ПрисоединенныеФайлы.Наименование + Расширение);
                КонецЕсли;
            КонецЕсли;
            
            Индекс = Индекс + 1;
        КонецЕсли;
    КонецЦикла;
КонецПроцедуры

Вариант 2. Сжатие PNG с потерями (Lossy PNG)

Если исходный файл PNG представляет собой сложную фотографию большого разрешения, стандартное сжатие без потерь может уменьшить размер файла всего на 10-15%. Если перед нами стоит задача подготовить изображения для публикации на сайте, где критически важен минимальный вес страниц, целесообразно использовать сжатие с потерями.

Для этого в ImageMagick мы можем принудительно уменьшить количество цветов в палитре изображения (сделать квантование). Это превратит тяжелый 24-битный PNG в оптимизированный 8-битный формат PNG8.

Чтобы задействовать этот механизм, добавьте в строку параметров ImageMagick ключ -colors 256. Это ограничит палитру ровно 256 цветами, что визуально практически незаметно на большинстве мониторов, но снизит вес картинки в 3–5 раз:


СтрокаПараметров = " -filter Lanczos -colors 256 -strip -define png:compression-filter=5 -define png:compression-level=9 -gaussian-blur 0.05 ";

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

Вариант 3. Современная альтернатива — нативная обработка встроенными средствами 1С

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

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

Рассмотрим по шагам, как переписать логику изменения размера и формата изображения встроенными средствами:

  1. Создаем объект Картинка на основании файла на диске.
  2. Инициализируем объект ОбрабатываемаяКартинка, передав исходную картинку в качестве параметра конструктора.
  3. Применяем необходимые трансформации, такие как изменение разрешения методом УстановитьРазмер или смена формата методом УстановитьФормат (например, перевод тяжелого PNG в компактный JPEG).
  4. Получаем измененный объект методом ПолучитьКартинку и сохраняем его на диск.

Проанализируем пример кода, реализующий этот кроссплатформенный подход:


&НаСервере
Процедура ОбработатьКартинкуВстроеннымиСредствами(СтароеИмя, НовоеИмяФайла)
    
    Попытка
        // Шаг 1: Загружаем картинку-источник
        КартинкаИсточник = Новый Картинка(СтароеИмя);
        
        // Шаг 2: Инициализируем обработчик
        ОбрабатываемаяКартинка = Новый ОбрабатываемаяКартинка(КартинкаИсточник);
        
        // Шаг 3: Пропорционально уменьшаем изображение. 
        // Если передать один из параметров как Неопределено, пропорции сохранятся автоматически.
        // Ограничим максимальную ширину картинки до 1200 пикселей.
        Ширина = 1200;
        Высота = Неопределено;
        ОбрабатываемаяКартинка.УстановитьРазмер(Ширина, Высота);
        
        // Дополнительно: если нам нужно переконвертировать PNG в JPEG для экономии места
        // ОбрабатываемаяКартинка.УстановитьФормат(ФорматКартинки.JPEG);
        
        // Шаг 4: Получаем результат и записываем на диск
        РезультатКартинка = ОбрабатываемаяКартинка.ПолучитьКартинку();
        РезультатКартинка.Записать(НовоеИмяФайла);
        
        Сообщить("Файл успешно обработан встроенными средствами 1С.");
    Исключение
        ЗаписатьЛогОшибок(ОписаниеОшибки());
        ВызватьИсключение "Не удалось обработать файл изображения: " + КраткоеПредставлениеОшибки(ИнформацияОбОшибке());
    КонецПопытки;
    
КонецПроцедуры

Сравнение подходов к обработке графики в 1С

Каждый из рассмотренных методов имеет свои преимущества и границы применимости. Проанализируем их:

Выбор конкретного решения зависит от требований вашего проекта к качеству оптимизации графики и ограничений вашей ИТ-инфраструктуры.

← На главную