Как выбрать номенклатуру с картинками и программно изменить размер изображений в 1С

Программист 1С v8.3 (Управляемые формы) 1С:Управление нашей фирмой Управленческий учет Торговля и дистрибуция
← На главную

В процессе эксплуатации типовых конфигураций, таких как 1С:Управление нашей фирмой (УНФ), пользователи часто сталкиваются с проблемой чрезмерного объема базы данных из-за загрузки фотографий товаров в высоком разрешении. Это приводит к замедлению работы системы, увеличению времени создания резервных копий и быстрому заполнению дискового пространства. В данной статье мы подробно разберем, как найти такие изображения и как оптимизировать их размер программными средствами.

Анализ структуры хранения изображений в 1С

Прежде чем приступать к написанию кода, проанализируем, где именно хранятся данные. В современных конфигурациях на базе Библиотеки стандартных подсистем (БСП) изображения номенклатуры не хранятся непосредственно в справочнике Номенклатура. Вместо этого используется вспомогательный справочник, обычно называемый НоменклатураПрисоединенныеФайлы. Сами файлы могут располагаться либо в информационной базе (в виде двоичных данных), либо в томах на диске.

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


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	НоменклатураПрисоединенныеФайлы.Ссылка КАК ФайлСсылка,
    |	НоменклатураПрисоединенныеФайлы.Наименование КАК ИмяФайла,
    |	НоменклатураПрисоединенныеФайлы.ВладелецФайла КАК Номенклатура,
    |	НоменклатураПрисоединенныеФайлы.Размер КАК РазмерБайт,
    |	НоменклатураПрисоединенныеФайлы.ПутьКФайлу КАК ПутьКФайлу,
    |	НоменклатураПрисоединенныеФайлы.Том.ПолныйПутьWindows КАК ПутьКТому
    |ИЗ
    |	Справочник.НоменклатураПрисоединенныеФайлы КАК НоменклатураПрисоединенныеФайлы
    |ГДЕ
    |	НоменклатураПрисоединенныеФайлы.ПометкаУдаления = ЛОЖЬ
    |	И НоменклатураПрисоединенныеФайлы.Размер > &МинимальныйРазмер";

Запрос.УстановитьПараметр("МинимальныйРазмер", 5000000); // Ищем файлы более 5 Мб
РезультатЗапроса = Запрос.Выполнить();

В этом запросе мы получаем ссылку на файл, его текущий размер и данные о томе хранения. Важно понимать, что если используется хранение в томах, то полный путь к файлу на диске складывается из ПутьКТому и ПутьКФайлу.

Метод 1: Использование Windows Image Acquisition (WIA)

Рассмотрим первый способ изменения размера — использование встроенной в ОС Windows библиотеки WIA. Этот метод удобен тем, что не требует установки сложного ПО, но библиотека должна быть зарегистрирована в системе. Проанализируем программный код, который загружает картинку, меняет ее разрешение и сохраняет результат.

Алгоритм работы с WIA.ImageFile выглядит следующим образом:

  1. Создаем COM-объекты для самого изображения и процессора фильтров.
  2. Загружаем исходный файл.
  3. Добавляем фильтр масштабирования (Scale).
  4. Устанавливаем максимальную ширину и высоту.
  5. Применяем фильтр и сохраняем файл.

// Пример использования WIA для изменения разрешения
objImageFile = Новый COMОбъект("WIA.ImageFile");
objImageProcess = Новый COMОбъект("WIA.ImageProcess");

// Загружаем файл
objImageFile.LoadFile("C:\Temp\SourceImage.jpg");

// Настраиваем фильтр масштабирования
objImageProcess.Filters.Add(objImageProcess.FilterInfos("Scale").FilterID);
// Указываем новые границы (например, не более 1000 пикселей по широкой стороне)
objImageProcess.Filters.Item(1).Properties.Item("MaximumWidth").Value = 1000;
objImageProcess.Filters.Item(1).Properties.Item("MaximumHeight").Value = 1000;

// Применяем изменения
objImageFile = objImageProcess.Apply(objImageFile);

// Сохраняем результат
objImageFile.SaveFile("C:\Temp\ResizedImage.jpg");

Важный нюанс: Данный метод изменяет геометрические размеры (разрешение) картинки, что влечет за собой уменьшение веса файла. Однако он не позволяет тонко управлять степенью сжатия JPEG (качеством).

Метод 2: Профессиональное сжатие через ImageMagick

Если нам необходимо не просто изменить размер, а именно «сжать» файл до определенного веса (например, не более 5 Мб) с сохранением максимального качества, лучше использовать внешнюю утилиту ImageMagick. Это мощный инструмент, который можно запускать из 1С в фоновом режиме.

Для работы этого метода необходимо скачать и установить ImageMagick на сервер, обязательно отметив при установке опцию «Install legacy utilities (e.g. convert)». Выясним, как вызвать эту программу из кода 1С:


// Путь к исполняемому файлу ImageMagick
ПутьККонвертеру = """C:\Program Files\ImageMagick\convert.exe""";

// Параметры: исходный файл, параметры сжатия, целевой файл
// -quality 75 задает качество JPEG
// -resize 1920x1080 ограничивает разрешение
ПараметрыЗапуска = ПутьККонвертеру + " ""C:\In.jpg"" -filter Lanczos -quality 75 -resize 1920x1080 ""C:\Out.jpg""";

// Запускаем приложение и ждем завершения
ЗапуститьПриложение(ПараметрыЗапуска, , Истина);

Проанализируем ключевой параметр -define jpeg:extent=4900kb. Это уникальная функция ImageMagick, которая будет итеративно подбирать степень сжатия, чтобы итоговый файл максимально приблизился к указанному размеру, но не превысил его. Это именно то, что требовалось в условии задачи.

Метод 3: Современный подход через «ОбработкаКартинок» (Платформа 8.3.10+)

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

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


// Получаем двоичные данные из файла или из базы
ДвоичныеДанныеКартинки = Новый ДвоичныеДанные(ПолныйПутьКФайлу);
Картинка = Новый Картинка(ДвоичныеДанныеКартинки);

// Создаем объект обработки
Обработка = Новый ОбработкаКартинок;
Обработка.УстановитьКартинку(Картинка);

// Если ширина больше 1920, уменьшаем пропорционально
Если Картинка.Ширина() > 1920 Тогда
    Обработка.ИзменитьРазмер(1920, Неопределено); // Высота рассчитается сама
КонецЕсли;

// Устанавливаем формат и качество сжатия (от 1 до 100)
Обработка.Записать("C:\Temp\Optimized.jpg", ФорматКартинки.JPEG, 70);

Этот метод позволяет эффективно управлять весом файлов прямо в коде 1С, сохраняя при этом высокую производительность.

Интеграция решения в систему

После того как мы выбрали подходящий метод сжатия, необходимо обновить данные в самой системе 1С. Если файл хранился в томе на диске, мы можем просто перезаписать его новым сжатым файлом. Однако обязательно нужно обновить реквизит Размер в справочнике НоменклатураПрисоединенныеФайлы, иначе в интерфейсе программы будет отображаться старая информация.

Рассмотрим финальный алгоритм обработки:

  1. Выполняем запрос для поиска файлов, размер которых превышает 5 Мб.
  2. Для каждого файла получаем его физическое расположение.
  3. Применяем один из методов сжатия (WIA, ImageMagick или ОбработкаКартинок).
  4. Записываем новый файл на место старого.
  5. Программно обновляем размер в карточке файла в 1С.
  6. При необходимости пересчитываем контрольную сумму файла (MD5), чтобы кеш браузеров и тонких клиентов обновился.

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

← На главную