При разработке интерфейсов на управляемых формах в «1С:Предприятие» программисты часто сталкиваются с задачей отображения изображений непосредственно в строках табличной части или динамического списка. Казалось бы, задача тривиальная: достаточно добавить колонку с видом Поле картинки и установить свойство размера в значение Пропорционально. Однако на практике изображение часто выводится в свой полный (физический) размер, растягивая строки таблицы и ломая весь интерфейс управляемой формы.
В этой статье мы подробно разберем, почему возникает такое поведение платформы, проанализируем механизмы рендеринга ячеек и рассмотрим два надежных способа решения этой проблемы: через тонкую настройку свойств элементов формы в конфигураторе и программным путем на сервере.
Для начала проанализируем ситуацию с точки зрения логики компоновщика интерфейса управляемых форм 1С. Когда мы устанавливаем для поля картинки свойство Размер картинки в значение Пропорционально, платформа пытается вписать изображение в границы отведенного контейнера (ячейки таблицы) с сохранением пропорций сторон.
Однако по умолчанию в свойствах таблиц управляемых форм включено автоматическое определение высоты строк. Если размеры ячейки жестко не ограничены, контейнер начинает подстраиваться под содержимое. Платформа видит «тяжелую» картинку высокого разрешения, расширяет ячейку под ее физический размер, а затем применяет масштабирование Пропорционально уже к этой растянутой ячейке. В результате картинка отображается в своем исходном гигантском масштабе. Чтобы победить это поведение, нам нужно применить один из следующих подходов.
Если вам нужно быстро вывести небольшие изображения (например, иконки или стандартные пиктограммы) без изменения программного кода, мы можем заставить платформу соблюдать границы контейнера с помощью правильной настройки свойств элементов формы. Разберем этот процесс по шагам:
Поле картинки.Пропорционально.Ширина = 10, Высота = 4.4).Такой подход отлично работает для простых задач, однако у него есть существенный минус. Если исходные файлы картинок весят по несколько мегабайт, клиентский компьютер будет тратить колоссальные ресурсы на скачивание и сжатие этих изображений «на лету» при скроллинге таблицы, что неизбежно приведет к зависаниям интерфейса.
Рассмотрим более профессиональный и отказоустойчивый метод решения проблемы, который используется в высоконагруженных тиражных решениях. Вместо того чтобы заставлять платформу сжимать тяжелые файлы на стороне клиента, мы будем генерировать облегченные миниатюры (превью) картинок на сервере в момент их загрузки или записи в базу данных.
Для реализации этого метода нам понадобятся встроенный объект ОбрабатываемаяКартинка и объект Картинка. Посмотрим на пример функции, которая принимает оригинальные двоичные данные изображения и возвращает уменьшенную копию с сохранением пропорций:
&НаСервере
Функция СформироватьПревьюКартинки(ДанныеФайла, МаксимальнаяШирина = 120, МаксимальнаяВысота = 120) Экспорт
// Получаем двоичные данные исходного файла изображения
ДвоичныеДанныеОригинала = ПолучитьДвоичныеДанныеИзХранилища(ДанныеФайла);
Если ДвоичныеДанныеОригинала = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
ИсходнаяКартинка = Новый Картинка(ДвоичныеДанныеОригинала);
// Используем специализированный объект платформы для работы с изображениями
ОбработкаИзображения = Новый ОбрабатываемаяКартинка(ИсходнаяКартинка);
// Получаем текущие размеры картинки в пикселях
ТекущаяШирина = ОбработкаИзображения.Ширина();
ТекущаяВысота = ОбработкаИзображения.Высота();
Если ТекущаяШирина = 0 Или ТекущаяВысота = 0 Тогда
Возврат Неопределено; // Некорректный формат файла
КонецЕсли;
// Вычисляем коэффициенты масштабирования для сохранения пропорций
КоэффициентШирины = ТекущаяШирина / МаксимальнаяШирина;
КоэффициентВысоты = ТекущаяВысота / МаксимальнаяВысота;
КоэффициентМасштабирования = Максимальный(КоэффициентШирины, КоэффициентВысоты);
// Изменяем размер только если оригинал больше требуемого превью
Если КоэффициентМасштабирования > 1 Тогда
НоваяШирина = ТекущаяШирина / КоэффициентМасштабирования;
НоваяВысота = ТекущаяВысота / КоэффициентМасштабирования;
// Корректируем размер изображения программно
ОбработкаИзображения.УстановитьРазмер(НоваяШирина, НоваяВысота);
КонецЕсли;
// Получаем готовую миниатюру в виде объекта Картинка
РезультатКартинка = ОбработкаИзображения.ПолучитьКартинку();
// Возвращаем двоичные данные для последующего сохранения в БД или кэш
Возврат РезультатКартинка.ПолучитьДвоичныеДанные();
КонецФункции
Разберем по шагам, как правильно внедрить этот механизм в вашу конфигурацию:
ХранилищеЗначения для хранения уменьшенной копии (превью) изображения.СформироватьПревьюКартинки и записывайте полученные двоичные данные в этот новый реквизит.Пропорционально.Этот способ гарантирует моментальный рендеринг строк, плавный скроллинг таблиц любой сложности и полностью решает проблему некорректного масштабирования изображений на управляемых формах 1С.