В процессе эксплуатации типовых конфигураций, таких как 1С:Управление нашей фирмой (УНФ), пользователи часто сталкиваются с проблемой чрезмерного объема базы данных из-за загрузки фотографий товаров в высоком разрешении. Это приводит к замедлению работы системы, увеличению времени создания резервных копий и быстрому заполнению дискового пространства. В данной статье мы подробно разберем, как найти такие изображения и как оптимизировать их размер программными средствами.
Прежде чем приступать к написанию кода, проанализируем, где именно хранятся данные. В современных конфигурациях на базе Библиотеки стандартных подсистем (БСП) изображения номенклатуры не хранятся непосредственно в справочнике Номенклатура. Вместо этого используется вспомогательный справочник, обычно называемый НоменклатураПрисоединенныеФайлы. Сами файлы могут располагаться либо в информационной базе (в виде двоичных данных), либо в томах на диске.
Разберем типичный запрос, который позволяет выбрать номенклатуру и связанные с ней файлы изображений. Мы будем использовать обращение к справочнику присоединенных файлов, так как именно там содержится информация о размере файла и пути к нему.
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| НоменклатураПрисоединенныеФайлы.Ссылка КАК ФайлСсылка,
| НоменклатураПрисоединенныеФайлы.Наименование КАК ИмяФайла,
| НоменклатураПрисоединенныеФайлы.ВладелецФайла КАК Номенклатура,
| НоменклатураПрисоединенныеФайлы.Размер КАК РазмерБайт,
| НоменклатураПрисоединенныеФайлы.ПутьКФайлу КАК ПутьКФайлу,
| НоменклатураПрисоединенныеФайлы.Том.ПолныйПутьWindows КАК ПутьКТому
|ИЗ
| Справочник.НоменклатураПрисоединенныеФайлы КАК НоменклатураПрисоединенныеФайлы
|ГДЕ
| НоменклатураПрисоединенныеФайлы.ПометкаУдаления = ЛОЖЬ
| И НоменклатураПрисоединенныеФайлы.Размер > &МинимальныйРазмер";
Запрос.УстановитьПараметр("МинимальныйРазмер", 5000000); // Ищем файлы более 5 Мб
РезультатЗапроса = Запрос.Выполнить();
В этом запросе мы получаем ссылку на файл, его текущий размер и данные о томе хранения. Важно понимать, что если используется хранение в томах, то полный путь к файлу на диске складывается из ПутьКТому и ПутьКФайлу.
Рассмотрим первый способ изменения размера — использование встроенной в ОС Windows библиотеки WIA. Этот метод удобен тем, что не требует установки сложного ПО, но библиотека должна быть зарегистрирована в системе. Проанализируем программный код, который загружает картинку, меняет ее разрешение и сохраняет результат.
Алгоритм работы с WIA.ImageFile выглядит следующим образом:
// Пример использования 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 (качеством).
Если нам необходимо не просто изменить размер, а именно «сжать» файл до определенного веса (например, не более 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, которая будет итеративно подбирать степень сжатия, чтобы итоговый файл максимально приблизился к указанному размеру, но не превысил его. Это именно то, что требовалось в условии задачи.
Начиная с версии платформы 8.3.10, в 1С появился встроенный объект ОбработкаКартинок. Это наиболее предпочтительный вариант, так как он работает кроссплатформенно и не требует внешних библиотек. Рассмотрим, как реализовать задачу с его помощью.
Разберем пример кода, который уменьшает картинку, если ее размер слишком велик:
// Получаем двоичные данные из файла или из базы
ДвоичныеДанныеКартинки = Новый ДвоичныеДанные(ПолныйПутьКФайлу);
Картинка = Новый Картинка(ДвоичныеДанныеКартинки);
// Создаем объект обработки
Обработка = Новый ОбработкаКартинок;
Обработка.УстановитьКартинку(Картинка);
// Если ширина больше 1920, уменьшаем пропорционально
Если Картинка.Ширина() > 1920 Тогда
Обработка.ИзменитьРазмер(1920, Неопределено); // Высота рассчитается сама
КонецЕсли;
// Устанавливаем формат и качество сжатия (от 1 до 100)
Обработка.Записать("C:\Temp\Optimized.jpg", ФорматКартинки.JPEG, 70);
Этот метод позволяет эффективно управлять весом файлов прямо в коде 1С, сохраняя при этом высокую производительность.
После того как мы выбрали подходящий метод сжатия, необходимо обновить данные в самой системе 1С. Если файл хранился в томе на диске, мы можем просто перезаписать его новым сжатым файлом. Однако обязательно нужно обновить реквизит Размер в справочнике НоменклатураПрисоединенныеФайлы, иначе в интерфейсе программы будет отображаться старая информация.
Рассмотрим финальный алгоритм обработки:
ОбработкаКартинок).Таким образом, мы не только очищаем место на диске, но и ускоряем работу пользователей с карточками товаров, так как браузеру больше не нужно загружать и масштабировать огромные изображения «на лету».