Как отобразить картинку из строки Base64 на управляемой форме 1С без сохранения в файл?

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

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

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

Понимание механизма работы управляемых форм с графикой

Для начала давайте разберем главное отличие управляемых форм от обычных (использовавшихся в 1С:Предприятие 8.2 и более ранних версиях). В обычных формах мы могли напрямую обратиться к элементу интерфейса и присвоить ему объект картинки через код вида ЭлементыФормы.ПолеКартинки.Картинка = Новый Картинка(ДвоичныеДанные). В управляемом приложении этот подход больше не работает.

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

  1. Реквизит формы, который выступает источником данных.
  2. Элемент формы с видом Поле картинки, связанный с этим реквизитом через свойство "ПутьКДанным".

Важнейший нюанс, на котором спотыкаются многие разработчики: тип реквизита формы должен быть Строка, а вовсе не Картинка или ДвоичныеДанные! В этом строковом реквизите должен храниться не сам бинарный код картинки и не строка Base64, а адрес временного хранилища, в которое мы предварительно поместили наши двоичные данные. Платформа 1С устроена таким образом, что поле картинки на клиенте автоматически считывает данные по указанному адресу временного хранилища, самостоятельно определяет формат файла (будь то PNG, JPEG, GIF или BMP) и отрисовывает его на экране пользователя.

Давайте пошагово разберем классический и наиболее производительный алгоритм реализации этой задачи.

Шаг 1. Настройка реквизитов и элементов управляемой формы

Прежде чем приступать к написанию программного кода, нам необходимо правильно подготовить саму форму в конфигураторе:

  1. Откроем редактор управляемой формы нашей обработки или документа.
  2. Перейдем на вкладку Реквизиты и создадим новый реквизит формы. Назовем его, например, АдресКартинкиНаФорме. В качестве типа данных выберем Строка (длину оставляем неограниченной).
  3. Перетащим созданный реквизит АдресКартинкиНаФорме в левое окно — в список элементов формы.
  4. Платформа автоматически создаст элемент управления. Убедимся, что в его свойствах установлен вид Поле картинки. Если это не так, выберем данный вид вручную из выпадающего списка.

Теперь форма полностью готова принимать данные. Перейдем к программной логике.

Шаг 2. Написание программного кода декодирования и вывода

Нам потребуется перевести исходную строку Base64 в объект ДвоичныеДанные, после чего отправить этот объект во временное хранилище и связать полученный адрес с реквизитом нашей формы. Поскольку работа с двоичными данными и временным хранилищем выполняется на стороне сервера, основную процедуру мы будем выполнять в серверном контексте.

Рассмотрим подробнее эталонный пример реализации данной процедуры:


&НаСервере
Процедура ОтобразитьКартинкуИзBase64НаСервере(Знач КодBase64)
    
    // Шаг 1. Декодируем строку Base64 во встроенный объект ДвоичныеДанные
    Попытка
        ДвоичныеДанныеКартинки = Base64Значение(КодBase64);
    Исключение
        ВызватьИсключение "Не удалось декодировать строку Base64. Возможно, строка повреждена.";
    КонецПопытки;
    
    // Шаг 2. Помещаем двоичные данные во временное хранилище.
    // Обратите внимание на второй параметр: передача УникальногоИдентификатора формы 
    // связывает время жизни временного хранилища с временем жизни самой формы.
    // Это гарантирует, что данные не исчезнут из памяти во время работы пользователя.
    АдресВХ = ПоместитьВоВременноеХранилище(ДвоичныеДанныеКартинки, УникальныйИдентификатор);
    
    // Шаг 3. Привязываем полученный адрес к реквизиту формы.
    // Платформа мгновенно отреагирует на изменение значения реквизита и обновит картинку на клиенте.
    АдресКартинкиНаФорме = АдресВХ;
    
КонецПроцедуры

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

Препятствие 1. Проблема заголовков и MIME-префиксов

Очень часто внешние веб-сервисы, браузерные скрипты или базы данных NoSQL отдают картинку не в чистом Base64, а с так называемым префиксом схемы Data URL. Выглядит это примерно так:

data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEASABIAAD...

Если мы попытаемся передать такую строку напрямую в стандартную функцию платформы Base64Значение(), то получим ошибку декодирования или пустой битый файл. Дело в том, что символы двоеточия, точки с запятой и запятой не входят в стандартный алфавит кодирования Base64. Функция 1С не умеет самостоятельно очищать эти метаданные.

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


// Находим позицию запятой, которая отделяет MIME-префикс от тела Base64
ПозицияЗапятой = СтрНайти(КодBase64, ",");

Если ПозицияЗапятой > 0 Тогда
    // Отрезаем все символы до запятой включительно
    ЧистыйКодBase64 = Сред(КодBase64, ПозицияЗапятой + 1);
Иначе
    ЧистыйКодBase64 = КодBase64;
КонецЕсли;

Использование этого несложного алгоритма убережет вашу программу от аварийного завершения при работе со сторонними API.

Препятствие 2. Переносы строк и URL-Safe кодирование

В зависимости от спецификаций систем-отправителей, строка Base64 может содержать нежелательные символы, препятствующие корректной обработке в 1С:

  1. Символы переноса строк (CRLF): Стандарты MIME часто требуют разбиения длинных Base64-строк на фрагменты по 76 символов с переносом строки. Хотя встроенные механизмы 1С стараются обрабатывать такие строки лояльно, на некоторых релизах платформы это может вызывать сбои или замедление работы. Рекомендуется превентивно избавляться от управляющих символов переноса строк с помощью функции СтрЗаменить().
  2. "Безопасный" алфавит Base64 для URL (URL-Safe): При передаче через GET-запросы символы + и / заменяются на более безопасные для браузеров символы - (дефис) и _ (подчеркивание). Перед отправкой такой строки в декодер 1С их обязательно нужно вернуть в исходное состояние.

Давайте дополним нашу серверную процедуру блоком предварительной нормализации строки:


// Очищаем от переносов строк и пробельных символов
ЧистаяСтрока = СтрЗаменить(ЧистаяСтрока, Символы.ПС, "");
ЧистаяСтрока = СтрЗаменить(ЧистаяСтрока, Символы.ВК, "");
ЧистаяСтрока = СтрЗаменить(ЧистаяСтрока, " ", "");

// Восстанавливаем стандартные символы Base64 из URL-Safe представления
ЧистаяСтрока = СтрЗаменить(ЧистаяСтрока, "-", "+");
ЧистаяСтрока = СтрЗаменить(ЧистаяСтрока, "_", "/");

Альтернативный метод вывода: Поле HTML документа

В некоторых сценариях классический метод с временным хранилищем может показаться избыточным. Например, если вам нужно вывести не просто одну картинку, а сформировать интерактивную карточку товара, где изображение гармонично сочетается с описанием, ценой и кнопками управления. Или если вы хотите избежать лишних серверных вызовов для перегонки бинарных данных во временное хранилище.

В таких случаях идеальным решением станет использование элемента формы Поле HTML документа. Этот элемент рендерится веб-браузером, встроенным в платформу 1С, и он "из коробки" понимает формат Data URL со всеми префиксами!

Для реализации этого метода:

  1. Создайте реквизит управляемой формы с типом Строка (например, ТекстHTMLКарточки).
  2. Разместите его на форме и укажите вид элемента Поле HTML документа.
  3. Сформируйте HTML-код, внедрив строку Base64 непосредственно в тег изображения.

Проанализируем пример формирования такого HTML-кода:


&НаКлиенте
Процедура ВывестиКартинкуЧерезHTML(КодBase64СПрефиксом)
    
    // В данном случае наличие префикса "data:image/jpeg;base64," ОБЯЗАТЕЛЬНО,
    // так как именно по нему HTML-браузер распознает тип контента.
    
    ТекстHTML = "
    |<html>
    |<body style='margin:0; padding:0; overflow:hidden; background-color: #f0f0f0;'>
    |   <div style='display: flex; justify-content: center; align-items: center; height: 100vh;'>
    |       <img src='" + КодBase64СПрефиксом + "' style='max-width:100%; max-height:100%; object-fit: contain;' />
    |   </div>
    |</body>
    |</html>";
    
    // Присваиваем сформированный HTML-текст реквизиту формы
    ТекстHTMLКарточки = ТекстHTML;
    
КонецПроцедуры

Этот способ примечателен тем, что мы можем использовать гибкую стилизацию CSS (например, центрирование картинки, добавление рамок, теней или эффектов при наведении), не нагружая серверную часть процессами декодирования и работы с временными таблицами СУБД.

Сравнительный анализ подходов

Давайте сопоставим оба рассмотренных метода, чтобы вы могли безошибочно выбрать подходящий под архитектуру вашего решения:

  1. Метод через Временное хранилище:
    • Плюсы: Использование стандартного платформенного элемента "Поле картинки". Корректно масштабируется стандартными средствами платформы. Минимальное потребление оперативной памяти на клиенте.
    • Минусы: Требует обязательного серверного контекстного вызова для работы функции Base64Значение() и помещения во временное хранилище. Чувствителен к некорректным символам и префиксам в строке Base64.
  2. Метод через Поле HTML документа:
    • Плюсы: Не требует декодирования на стороне сервера 1С. Позволяет создавать сложные интерактивные макеты вокруг картинки с использованием CSS/JS. Автоматически поддерживает MIME-префиксы.
    • Минусы: Повышенное потребление ресурсов клиентского компьютера (рендеринг веб-компонента). Сложнее кастомизировать внешний вид рамки поля HTML-документа, чтобы он полностью сливался со стандартным интерфейсом 1С.

Итоговый эталонный шаблон кода для работы через Временное хранилище

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


&НаСервере
Процедура ЗагрузитьИОтобразитьКартинкуИзBase64(Знач ВходнойКодBase64)
    
    // 1. Проверяем строку на пустоту
    Если ПустаяСтрока(ВходнойКодBase64) Тогда
        Возврат;
    КонецЕсли;
    
    // 2. Очищаем от возможных MIME-префиксов схемы Data URL
    ПозицияЗапятой = СтрНайти(ВходнойКодBase64, ",");
    РабочаяСтрока = ?(ПозицияЗапятой > 0, Сред(ВходнойКодBase64, ПозицияЗапятой + 1), ВходнойКодBase64);
    
    // 3. Удаляем нечитаемые символы переносов строк и лишние пробелы
    РабочаяСтрока = СтрЗаменить(РабочаяСтрока, Символы.ПС, "");
    РабочаяСтрока = СтрЗаменить(РабочаяСтрока, Символы.ВК, "");
    РабочаяСтрока = СтрЗаменить(РабочаяСтрока, " ", "");
    
    // 4. Корректируем символы URL-Safe Base64
    РабочаяСтрока = СтрЗаменить(РабочаяСтрока, "-", "+");
    РабочаяСтрока = СтрЗаменить(РабочаяСтрока, "_", "/");
    
    Попытка
        // 5. Выполняем декодирование в бинарные данные 1С
        ДвоичныеДанные = Base64Значение(РабочаяСтрока);
        
        // 6. Помещаем во временное хранилище текущего сеанса формы
        АдресВременногоХранилищаКартинки = ПоместитьВоВременноеХранилище(ДвоичныеДанные, УникальныйИдентификатор);
        
        // Связанное поле картинки на форме сразу отобразит изображение
        АдресКартинкиНаФорме = АдресВременногоХранилищаКартинки;
        
    Исключение
        // Выводим диагностическое сообщение пользователю в случае форс-мажора
        ВызватьИсключение "Ошибка обработки графических данных Base64: " + КраткоеПредставлениеОшибки(ИнформацияОбОшибке());
    КонецПопытки;
    
КонецПроцедуры

Используя данный шаблон, вы полностью застрахуете логику работы вашей конфигурации от некорректных данных внешних API, избавите жесткие диски пользователей от мусорных временных файлов и обеспечите максимально быструю скорость отрисовки интерфейса управляемых форм 1С.

← На главную