Как наложить одно изображение на другое в управляемых формах 1С?

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

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

Метод 1: Использование табличного документа как графического контейнера

Это один из самых гибких способов реализации наложения внутри интерфейса 1С без использования сторонних технологий. Суть метода заключается в том, что вместо элемента Поле картинки на форму помещается Поле табличного документа. Табличный документ в 1С — это не только сетка ячеек, но и полноценный графический слой, позволяющий работать с объектами типа РисунокТабличногоДокумента.

Разберем по шагам, как реализовать наложение через коллекцию Рисунки:

  1. Подготовка контейнера: Разместим на форме поле с типом ТабличныйДокумент. Назовем его, например, ПолеПросмотра. Отключим у него отображение сетки, заголовков строк и колонок, чтобы оно выглядело как обычная область для картинки.
  2. Программное добавление слоев: Для каждого изображения, которое должно стать слоем, мы создаем новый объект в коллекции Рисунки.
  3. Управление прозрачностью: Для корректного наложения необходимо использовать изображения в формате PNG с альфа-каналом. В коде 1С крайне важно установить свойство Узор в значение БезУзора, иначе фон картинки может перекрыть нижние слои.

Рассмотрим пример кода для наложения двух картинок:


// ТабДок - это наше ПолеТабличногоДокумента на форме
ТабДок.Очистить();

// Добавляем первый слой (основная картинка)
КартинкаОснова = ПолучитьКартинкуОсновы(); // Функция получения объекта Картинка
РисунокОснова = ТабДок.Рисунки.Добавить(ТипРисункаТабличногоДокумента.Картинка);
РисунокОснова.Картинка = КартинкаОснова;
РисунокОснова.Расположить(ТабДок.Область("R1C1:R20C10")); // Задаем размер области
РисунокОснова.РазмернаяКартинка = РазмернаяКартинка.АвтоРазмер;
РисунокОснова.Узор = ТипУзораТабличногоДокумента.БезУзора;

// Добавляем второй слой (например, фурнитура поверх окна)
КартинкаСлой = ПолучитьКартинкуФурнитуры();
РисунокСлой = ТабДок.Рисунки.Добавить(ТипРисункаТабличногоДокумента.Картинка);
РисунокСлой.Картинка = КартинкаСлой;
// Располагаем в тех же координатах, что и первый рисунок для наложения
РисунокСлой.Расположить(ТабДок.Область("R1C1:R20C10"));
РисунокСлой.Узор = ТипУзораТабличногоДокумента.БезУзора;

// Управляем порядком слоев (Z-order)
// Чем выше индекс в коллекции или параметр ZOrder, тем "выше" картинка к пользователю
РисунокСлой.Порядок = 1; 

Проанализируем важный нюанс: в сообщении форума пользователь пытался присвоить картинку свойству Область.Картинка. Это ошибка, так как свойство ячейки Картинка заменяет содержимое ячейки и не поддерживает наложение. Правильный путь — работа именно с коллекцией Рисунки, которые «летают» над сеткой таблицы.

Метод 2: Поле HTML-документа и CSS-позиционирование

Если задача требует высокой точности (позиционирование до пикселя) или динамической анимации, стоит рассмотреть использование Поля HTML-документа. В современной платформе 1С это поле базируется на движке WebKit (в тонком клиенте) или браузере, что дает доступ к возможностям HTML5 и CSS3.

Выясним причину, почему этот метод считается наиболее профессиональным: он позволяет передавать изображения через временное хранилище или в виде Base64-строк и управлять ими с помощью стандартного CSS-свойства z-index.

Алгоритм реализации следующий:

  1. Сформируем HTML-строку, в которой создадим родительский контейнер (div) с относительным позиционированием (position: relative).
  2. Внутри контейнера разместим элементы img с абсолютным позиционированием (position: absolute).
  3. Для каждого слоя зададим z-index, где большее значение соответствует верхнему слою.

Пример формирования текста HTML в коде 1С:


АдресКартинки1 = ПоместитьВоВременноеХранилище(ДанныеКартинки1);
АдресКартинки2 = ПоместитьВоВременноеХранилище(ДанныеКартинки2);

ТекстHTML = 
"<html>
|<body style='margin:0; padding:0; overflow:hidden;'>
|   <div style='position:relative; width:100%; height:100%;'>
|       <img src='" + АдресКартинки1 + "' style='position:absolute; top:0; left:0; z-index:1;' />
|       <img src='" + АдресКартинки2 + "' style='position:absolute; top:10px; left:50px; z-index:2;' />
|   </div>
|</body>
|</html>";

Этот метод идеален для конфигураций, работающих через веб-клиент, так как он полностью нативен для браузера.

Метод 3: Программное слияние изображений через SVG

Рассмотрим современный подход, который позволяет обойтись без внешних компонент и при этом получить итоговое изображение, которое можно вывести в обычное Поле картинки. Платформа 1С поддерживает формат SVG (Scalable Vector Graphics). SVG — это текстовый XML-документ, в который можно внедрять растровые данные.

Мы можем программно собрать строку SVG, в которой будут перечислены все наши картинки. Это позволит 1С воспринимать «сборку» как один единственный графический объект.


// Пример формирования SVG с двумя слоями
Base64Картинка1 = Base64Строка(ДвоичныеДанные1);
Base64Картинка2 = Base64Строка(ДвоичныеДанные2);

ТекстSVG = 
"<svg width='500' height='500' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'>
|   <image href='data:image/png;base64," + Base64Картинка1 + "' x='0' y='0' width='500' height='500'/>
|   <image href='data:image/png;base64," + Base64Картинка2 + "' x='100' y='100' width='50' height='50'/>
|</svg>";

МояКартинка = Новый Картинка(ДвоичныеДанныеИзСтроки(ТекстSVG));
// Теперь МояКартинка можно вывести в обычный реквизит формы с типом Картинка

Метод 4: Динамическое управление видимостью (при малом количестве комбинаций)

Если вариантов наложения немного (например, только два состояния: «Товар» и «Товар с пометкой Акция»), самым простым решением будет использование нескольких элементов Поле картинки, расположенных рядом, или переключение видимости.

Проанализируем ситуацию, описанную в сообщении №5: если количество слоев (окно, ручки, форточка, рама) растет, количество готовых комбинаций картинок становится колоссальным. В этом случае метод предварительной заготовки всех вариантов («картинка двух видов») не подходит, и следует возвращаться к динамической сборке (Метод 1 или Метод 3).

Рекомендации по выбору решения

Подведем итог и выберем оптимальный путь в зависимости от условий задачи:

Важно помнить о производительности: при активации строки в списке (сообщение №13) код формирования изображения должен быть максимально оптимизирован. Не рекомендуется выполнять тяжелые операции слияния файлов на диске при каждом перемещении курсора по списку. Оптимальным будет кэширование сформированных картинок или использование легких SVG-структур.

← На главную