При разработке прикладных решений в 1С часто возникает задача привязать графические изображения к объектам конфигурации: фотографии товаров, сканы документов или фото автомобилей. Для этого нередко используют регистры сведений с ресурсом типа ХранилищеЗначения. Разберем подробно, как правильно программно записать изображение в регистр, как извлечь его и отобразить на форме, а также проанализируем нюансы производительности и альтернативные способы хранения.
Рассмотрим процесс записи графического файла с диска в ресурс регистра сведений. Для эффективного использования дискового пространства упакуем двоичные данные в ХранилищеЗначения с использованием сжатия данных.
Разберем пример создания новой записи через МенеджерЗаписи:
Файл = Новый Файл(ИмяФайла);
Если Файл.Существует() И Файл.ЭтоФайл() Тогда
НовЗапись = РегистрыСведений.ФотоАвтомобилей.СоздатьМенеджерЗаписи();
НовЗапись.Модель = Стр.Модель;
НовЗапись.Цвет = Цвет;
Попытка
// Создаем объект Картинка и упаковываем его в ХранилищеЗначения со сжатием
Данные = Новый ХранилищеЗначения(Новый Картинка(Файл.ПолноеИмя, Ложь), Новый СжатиеДанных(9));
НовЗапись.Картинка = Данные;
НовЗапись.Записать();
Исключение
Сообщить("Ошибка добавления файла! Возможно, файл заблокирован другой программой", СтатусСообщения.Внимание);
КонецПопытки;
КонецЕсли;
Обратим внимание на параметр сжатия: конструктор Новый СжатиеДанных(9) обеспечивает максимальную степень упаковки данных перед помещением в базу данных.
Выясним, как извлечь сохраненную картинку с помощью запроса и вывести ее в поле формы. В обычном интерфейсе элемент управления напрямую поддерживает установку объекта Картинка.
Посмотрим на пример извлечения и вывода:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ФотоАвтомобилей.Картинка КАК ХранилищеКартинки
|ИЗ
| РегистрСведений.ФотоАвтомобилей КАК ФотоАвтомобилей
|ГДЕ
| ФотоАвтомобилей.Модель = &Модель
| И ФотоАвтомобилей.Цвет = &Цвет";
Запрос.УстановитьПараметр("Модель", Модель);
Запрос.УстановитьПараметр("Цвет", Цвет);
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() Тогда
// Извлекаем объект из ХранилищаЗначения
ДанныеКартинки = Выборка.ХранилищеКартинки.Получить();
Если ТипЗнч(ДанныеКартинки) = Тип("Картинка") Тогда
ЭлементыФормы.ПолеПредварительногоПросмотра.Картинка = ДанныеКартинки;
Иначе
ЭлементыФормы.ПолеПредварительногоПросмотра.Картинка = БиблиотекаКартинок.Скрепка;
КонецЕсли;
КонецЕсли;
В управляемом интерфейсе прямое присвоение объекта Картинка элементу формы не применяется. Поле формы связывается с реквизитом типа Строка, содержащим навигационную ссылку или адрес во временном хранилище.
Разберем по шагам два основных способа работы в клиент-серверной архитектуре:
Получить() из ХранилищеЗначения, вызываем ПоместитьВоВременноеХранилище() с передачей УникальныйИдентификатор формы и присваиваем полученный адрес строковому реквизиту формы.ПолучитьНавигационнуюСсылку(), передавая ключ записи регистра сведений и имя ресурса. В этом случае платформа самостоятельно подгрузит двоичные данные по сформированному URL.Проанализируем технические нюансы и возможные проблемы, возникающие при активном сохранении изображений в базе данных:
ХранилищеЗначения нагружает сетевой трафик и серверные процессы. Крайне не рекомендуется включать такие поля в динамические списки без жесткой необходимости.Чтобы избежать падения производительности, рекомендуется применять следующие архитектурные подходы:
ОбработкаКартинок уменьшайте разрешение и размер фото при загрузке. Легкую миниатюру (превью) можно хранить в регистре для быстрого вывода в интерфейсе, а оригинал — загружать отдельно при детальном просмотре.ПоместитьФайлНаСерверАсинх), чтобы не блокировать интерфейс пользователя.