Как обеспечить прозрачность фона картинок в Табличном документе 1С при программном добавлении?

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

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

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

Мы сталкиваемся с такой ситуацией: у нас есть картинка, например, в формате PNG или GIF, которая в графическом редакторе была обработана таким образом, что ее фон стал прозрачным. При этом, если мы вставляем эту же картинку непосредственно в макет Табличного документа через Конфигуратор 1С, то прозрачность сохраняется идеально – через картинку проступают элементы документа, расположенные под ней. Но стоит нам попытаться добавить такую же картинку программно, используя код 1С, как мы видим, что прозрачность исчезает, и фон картинки становится непрозрачным. Почему так происходит?

Давайте проанализируем ситуацию. Разработчик, столкнувшийся с этой проблемой, подтверждает, что он:

  1. Использует картинки с прозрачным фоном, обработанные в онлайн-редакторе (форматы PNG, GIF).
  2. При создании объекта Картинка из файла или двоичных данных, всегда устанавливает параметр прозрачности в Истина: Новый Картинка(АдресФайлаФаксимиле,Истина).
  3. Не использует второй параметр в конструкторе Картинка, основываясь на справке, которая указывает, что этот параметр "используется только для картинок, формат которой не поддерживает прозрачности".

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

Основная причина потери прозрачности заключается в том, что при программном добавлении картинок в табличный документ 1С, даже если исходный файл имеет прозрачный фон (например, PNG или GIF), платформа может по умолчанию устанавливать фоновый цвет для элемента "Рисунок" в табличном документе. Этот фоновый цвет перекрывает прозрачность исходного изображения. Это происходит потому, что свойство ЦветФона у объекта РисунокТабличногоДокумента имеет некое значение по умолчанию, которое не является прозрачным.

Анализируем попытки решения и их результаты

В ходе поиска решения разработчики, как правило, предпринимают различные шаги, чтобы добиться желаемого эффекта. Рассмотрим наиболее распространенные попытки и выясним, почему они не всегда приводят к успеху в данном случае:

  1. Передача двоичных данных картинки: Мы часто видим, что картинка сначала преобразуется в двоичные данные на клиенте, а затем эти данные передаются на сервер для создания объекта Картинка и последующего размещения в Табличном документе. Этот подход является стандартным и правильным для клиент-серверного взаимодействия, но сам по себе он не гарантирует сохранение прозрачности фона. Пример из исходного сообщения:
    
    &НаКлиенте
    Процедура ВставитьФаксимиле(Команда)
        // ... проверка заполнения АдресаФайлаФаксимиле
        СодержимоеКартинки = Новый Картинка(АдресФайлаФаксимиле,Истина);
        ВставитьФаксимилеВТД(СодержимоеКартинки.ПолучитьДвоичныеДанные());
    КонецПроцедуры
    
    Здесь мы видим правильный способ получения двоичных данных. Однако, проблема прозрачности возникает позже, на этапе создания самого рисунка в ТД.
  2. Использование параметра "Прозрачный фон" в конструкторе Новый Картинка(): Как мы уже упоминали, существует необязательный булевый параметр, который определяет, будет ли использован цвет прозрачности при создании картинки. Синтаксис-помощник указывает, что он "Используется только для картинок, формат которой не поддерживает прозрачности." За цвет фона в этом случае принимается цвет последнего пикселя (правый-нижний). Если наша картинка имеет формат, поддерживающий альфа-канал (например, PNG или GIF), этот параметр, строго говоря, не должен быть решающим, поскольку прозрачность уже "зашита" в сам файл. Более того, его установка в Истина не помогла автору вопроса.
  3. Конвертация форматов: Были предположения, что прозрачность доступна только для определенных форматов, например BMP, JPG и TIFF, или наоборот, только для PNG. Разработчик пробовал конвертировать картинки в GIF и PNG, добиваясь прозрачности в онлайн-редакторах. Однако, даже после конвертации и подтверждения прозрачности при вставке через Конфигуратор, программный вывод все равно терял прозрачность. Это окончательно указывает на то, что формат файла не является корневой причиной проблемы в данном контексте, так как PNG и GIF однозначно поддерживают прозрачность через альфа-канал.

Таким образом, мы выяснили, что ни способ передачи данных, ни параметры конструктора Картинка, ни даже формат самого изображения не решают проблему программной потери прозрачности. Это подводит нас к мысли, что необходимо воздействовать непосредственно на свойства объекта РисунокТабличногоДокумента.

Находим ключевое решение: свойство ЦветФона

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

Ключевой шаг к обеспечению прозрачности: Мы должны явно установить свойство ЦветФона в прозрачное значение. Для этого мы используем конструктор Новый Цвет() без параметров.

Рассмотрим подробнее, почему Рисунок.ЦветФона = Новый Цвет(); работает:

Это простое, но критически важное действие устраняет "дефолтный" непрозрачный фон, который 1С могла бы установить автоматически при программном создании рисунка.

Пошаговое руководство по реализации прозрачности

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

  1. Получаем двоичные данные картинки на клиенте.

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

    
    &НаКлиенте
    Процедура ВставитьФаксимиле(Команда)
        Если Не ЗначениеЗаполнено(АдресФайлаФаксимиле) Тогда
            Сообщить("Выберите пример картинки факсимиле!");
            Возврат;
        КонецЕсли;
    
        // Создаем объект Картинка на клиенте из выбранного файла
        // Второй параметр Истина здесь не критичен для PNG/GIF с альфа-каналом,
        // но не повредит и может быть полезен для других форматов.
        СодержимоеКартинки = Новый Картинка(АдресФайлаФаксимиле, Истина);
    
        // Передаем двоичные данные картинки на сервер для дальнейшей обработки
        ВставитьФаксимилеВТДНаСервере(СодержимоеКартинки.ПолучитьДвоичныеДанные());
    КонецПроцедуры
    
  2. Передаем данные на сервер.

    Двоичные данные передаются в серверную процедуру, где будет происходить основная работа с Табличным документом.

    
    &НаСервере
    Процедура ВставитьФаксимилеВТДНаСервере(ДД_Факсимиле, Лево = Неопределено, Верх = Неопределено)
        // Убедитесь, что ТабличныйДокумент инициализирован (например, как реквизит формы)
        Если ТабличныйДокумент = Неопределено Тогда
            Сообщить("Табличный документ не инициализирован!");
            Возврат;
        КонецЕсли;
    
        // Создаем новый рисунок в коллекции Рисунки ТабличногоДокумента
        НоваяФаксимиле = ТабличныйДокумент.Рисунки.Добавить(ТипРисункаТабличногоДокумента.Картинка);
    
  3. Присваиваем картинку рисунку.

    На основе полученных двоичных данных создаем новый объект Картинка и присваиваем его свойству Картинка нашего РисункаТабличногоДокумента.

    
    // Создаем объект Картинка из двоичных данных, переданных с клиента
    НоваяФаксимиле.Картинка = Новый Картинка(ДД_Факсимиле, Истина);
    
  4. Критически важный шаг: устанавливаем прозрачность фона.

    Это самый важный шаг для решения проблемы. Мы явно устанавливаем свойство ЦветФона рисунка в прозрачное значение.

    
    // *** Ключевой момент для обеспечения прозрачности ***
    НоваяФаксимиле.ЦветФона = Новый Цвет();
    
  5. Настраиваем другие свойства рисунка.

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

    
        // Дополнительные настройки рисунка:
        НоваяФаксимиле.Линия = Новый Линия(ТипЛинииРисункаТабличногоДокумента.НетЛинии); // Отсутствие рамки
        НоваяФаксимиле.РазмерКартинки = РазмерКартинки.АвтоРазмер; // Или другой способ масштабирования (Например, Растянуть)
        НоваяФаксимиле.Высота = 10; // Установите нужную высоту в единицах табличного документа
        НоваяФаксимиле.Ширина = 10; // Установите нужную ширину в единицах табличного документа
    
        // Формируем уникальное имя для рисунка
        // Предполагаем, что СчетчикКартинок инициализирован и инкрементируется
        // СчетчикКартинок = СчетчикКартинок + 1;
        НоваяФаксимиле.Имя = "ФаксимилеРазные" + Формат(СчетчикКартинок, "ЧГ=");
    
        // Если нужно позиционировать рисунок, используйте Лево, Верх, Право, Низ
        // Например, для позиционирования в указанных координатах:
        // Если Лево <> Неопределено И Верх <> Неопределено Тогда
        //     НоваяФаксимиле.Лево = Лево;
        //     НоваяФаксимиле.Верх = Верх;
        //     // Если Высота и Ширина не заданы явно, они будут определены по размеру картинки
        //     // или придется рассчитывать Правый и Нижний края
        //     // НоваяФаксимиле.Право = Лево + НоваяФаксимиле.Ширина;
        //     // НоваяФаксимиле.Низ = Верх + НоваяФаксимиле.Высота;
        // КонецЕсли;
    
        // Если вы сохраняете информацию о рисунках в дополнительной таблице или коллекции:
        // СтрокаТаблицыФаксимиле = ПечатиИПодписиРазные.Добавить;
        // СтрокаТаблицыФаксимиле.ПечатьИлиПодпись = ТипФаксимилеРазные;
        // СтрокаТаблицыФаксимиле.ИмяКартинкиВТД = НоваяФаксимиле.Имя;
        // СтрокаТаблицыФаксимиле.СамаКартинка = НоваяФаксимиле.Картинка;
        // СтрокаТаблицыФаксимиле.Координаты = "{0,0}";
    КонецПроцедуры
    

Подробный пример кода

Объединим все шаги в полноценный пример кода, который позволит вам программно вставлять картинки с прозрачным фоном в Табличный документ:


// Предполагаемые переменные/реквизиты формы:
// - ТабличныйДокумент (тип ТабличныйДокумент)
// - АдресФайлаФаксимиле (тип Строка, содержит путь к файлу картинки)
// - СчетчикКартинок (тип Число, для уникальности имен рисунков)

&НаКлиенте
Процедура ВставитьФаксимиле(Команда)
    // Проверяем, выбран ли файл картинки
    Если Не ЗначениеЗаполнено(АдресФайлаФаксимиле) Тогда
        Сообщить("Выберите пример картинки факсимиле!");
        Возврат;
    КонецЕсли;

    // 1. Создаем объект Картинка на клиенте из выбранного файла.
    // Параметр 'Истина' для прозрачности может быть полезен, но не является единственным решением.
    СодержимоеКартинки = Новый Картинка(АдресФайлаФаксимиле, Истина);

    // 2. Передаем двоичные данные картинки на сервер для дальнейшей обработки.
    // Важно: в реальном приложении АдресФайлаФаксимиле лучше получать через диалог выбора файла
    // или из временного хранилища, чтобы избежать прямого доступа к файловой системе клиента на сервере.
    ВставитьФаксимилеВТДНаСервере(СодержимоеКартинки.ПолучитьДвоичныеДанные());
КонецПроцедуры

&НаСервере
Процедура ВставитьФаксимилеВТДНаСервере(ДД_Факсимиле, Лево = Неопределено, Верх = Неопределено)
    // Проверяем, инициализирован ли ТабличныйДокумент
    Если ТабличныйДокумент = Неопределено Тогда
        Сообщить("Табличный документ не инициализирован!");
        Возврат;
    КонецЕсли;

    // Увеличиваем счетчик для формирования уникального имени рисунка.
    // Убедитесь, что 'СчетчикКартинок' инициализирован, например, в ПриСозданииНаСервере
    // Если СчетчикКартинок = Неопределено Тогда
    //     СчетчикКартинок = 0;
    // КонецЕсли;
    // СчетчикКартинок = СчетчикКартинок + 1; // Раскомментировать, если используется

    // 3. Создаем новый рисунок типа "Картинка" в коллекции рисунков ТабличногоДокумента.
    НоваяФаксимиле = ТабличныйДокумент.Рисунки.Добавить(ТипРисункаТабличногоДокумента.Картинка);

    // 4. Создаем объект Картинка из двоичных данных и присваиваем его свойству Картинка рисунка.
    // Параметр 'Истина' (прозрачный фон) здесь также полезен.
    НоваяФаксимиле.Картинка = Новый Картинка(ДД_Факсимиле, Истина);

    // 5. *** КЛЮЧЕВОЕ ДЕЙСТВИЕ для обеспечения прозрачности фона рисунка в Табличном документе ***
    // Устанавливаем свойство ЦветФона в "прозрачный" цвет, создавая Новый Цвет() без параметров.
    НоваяФаксимиле.ЦветФона = Новый Цвет();

    // 6. Настраиваем дополнительные свойства рисунка.
    // Убираем линию (рамку) вокруг рисунка
    НоваяФаксимиле.Линия = Новый Линия(ТипЛинииРисункаТабличногоДокумента.НетЛинии);
    
    // Определяем, как картинка будет масштабироваться в границах рисунка.
    // Можно использовать АвтоРазмер (размер картинки по умолчанию), Растянуть (растянуть до размеров рисунка),
    // или ИсходныйРазмер (показать картинку в исходном размере, если рисунок больше).
    НоваяФаксимиле.РазмерКартинки = РазмерКартинки.АвтоРазмер; 
    
    // Устанавливаем размеры рисунка в единицах табличного документа.
    // Если вы используете АвтоРазмер, эти значения могут быть переопределены размерами самой картинки.
    НоваяФаксимиле.Высота = 10; 
    НоваяФаксимиле.Ширина = 10; 

    // Присваиваем уникальное имя рисунку. Это полезно для последующего обращения к нему.
    НоваяФаксимиле.Имя = "ФаксимилеРазные" + Формат(СчетчикКартинок, "ЧГ="); 

    // Если требуется точное позиционирование рисунка, устанавливаем его координаты.
    // Лево и Верх - координаты левого верхнего угла рисунка.
    Если Лево <> Неопределено Тогда
        НоваяФаксимиле.Лево = Лево;
    КонецЕсли;
    Если Верх <> Неопределено Тогда
        НоваяФаксимиле.Верх = Верх;
    КонецЕсли;

    // Пример сохранения метаданных о картинке, если это требуется для вашей логики:
    // СтрокаТаблицыФаксимиле = ПечатиИПодписиРазные.Добавить;
    // СтрокаТаблицыФаксимиле.ПечатьИлиПодпись = ТипФаксимилеРазные;
    // СтрокаТаблицыФаксимиле.ИмяКартинкиВТД = НоваяФаксимиле.Имя;
    // СтрокаТаблицыФаксимиле.СамаКартинка = НоваяФаксимиле.Картинка;
    // СтрокаТаблицыФаксимиле.Координаты = "{0,0}";
КонецПроцедуры

Важные нюансы и дополнительные рекомендации

Чтобы глубже понять механизм работы с прозрачностью картинок в 1С и избежать других подводных камней, рассмотрим несколько важных аспектов:

  1. Поддерживаемые форматы изображений с прозрачностью:

    1С:Предприятие поддерживает прозрачность для таких форматов как PNG и GIF. Эти форматы наиболее подходят для пиктограмм и изображений, где важна попиксельная прозрачность (через альфа-канал для PNG или индекс прозрачности для GIF). Хотя в обсуждении упоминались BMP, JPG и TIFF, для этих форматов прозрачность обычно реализуется путем замены определенного цвета на прозрачный, а не через альфа-канал, как в PNG. Рекомендуем использовать PNG для лучшего качества и более гибкой прозрачности, а GIF – для простых анимаций или изображений с ограниченным количеством цветов.

  2. Параметр "Прозрачный фон" в конструкторе Картинка:

    Как мы уже упоминали, в конструкторе объекта Картинка существует необязательный булевый параметр Прозрачный фон. Он определяет, будет ли использоваться цвет прозрачности при создании картинки и применяется только для форматов, которые не поддерживают прозрачность изначально (например, BMP или JPG). За цвет фона в этом случае принимается цвет последнего пикселя (правый-нижний). Если вы работаете с PNG или GIF, этот параметр не является критически важным для обеспечения прозрачности, поскольку она уже встроена в файл. Тем не менее, его установка в Истина не повредит и может помочь в ситуациях, когда требуется эмуляция прозрачности для других форматов.

  3. Особенности при экспорте и печати:

    Иногда, даже если прозрачность корректно отображается в 1С, могут возникать проблемы при печати или экспорте табличных документов (например, в PDF). Это связано с особенностями работы виртуальных принтеров или конвертеров форматов. Если вы столкнулись с подобной проблемой, мы рекомендуем проверить настройки печати или экспорта, а также попробовать разные версии PDF-принтеров, если это применимо.

  4. Редактирование картинок в 1С:

    Встроенный редактор картинок в 1С поддерживает работу с альфа-каналом для PNG-изображений с разрешением более 8 бит на пиксель, что позволяет задавать прозрачность для любого цвета. Также в редакторе есть возможность выбрать прозрачный фон. Если вы создаете или модифицируете изображения прямо в 1С, эти инструменты могут быть полезны для подготовки картинок с нужной прозрачностью.

  5. Почему при вставке через Конфигуратор все работает?

    Когда картинка вставляется через Конфигуратор, 1С предоставляет опцию "Установить прозрачный цвет", где можно выбрать цвет, который будет считаться прозрачным. Кроме того, при ручной вставке платформа может автоматически настраивать необходимые свойства объекта РисунокТабличногоДокумента, включая его ЦветФона, таким образом, чтобы прозрачность изображения сохранялась. Это объясняет разницу в поведении между ручной и программной вставкой: при программном подходе мы должны явно указать 1С, что фон рисунка должен быть прозрачным, используя Рисунок.ЦветФона = Новый Цвет();.

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

← На главную