Как преобразовать строку формата Base64 (Data URL) в картинку в 1С?

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

Рассмотрим распространенную техническую задачу: при обработке содержимого объекта ФорматированныйДокумент, выгрузок из HTML или интеграции с веб-сервисами графические данные передаются не в виде привычного файла, а в виде текстовой строки формата Data URI (например, data:image/png;base64,iVBORw0KGgoAAAANSU...). Для вывода такого изображения в табличный документ, макет или на управляемую форму его необходимо преобразовать в объект 1С Картинка.

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

Структура строки Data URL

Проанализируем структуру текстовой строки формата Data URI. Согласно спецификации RFC 2397, она состоит из нескольких основных элементов:

  1. Префикс схемы: data:
  2. MIME-тип содержимого: например, image/png, image/jpeg или image/gif
  3. Указатель кодировки: ;base64
  4. Разделитель метаданных и данных: символьная запятая ,
  5. Тело данных: зашифрованное в кодировку Base64 бинарное содержимое изображения

Так как MIME-тип зависит от формата файла (PNG, JPEG, WebP, SVG), жестко отрезать фиксированное количество символов (например, первые 22 или 23 символа) не рекомендуется. Наиболее универсальное решение — искать первое вхождение запятой и отсекать всю левую часть строки.

Универсальный алгоритм извлечения картинки из Base64

Рассмотрим пошаговый процесс преобразования строки Data URL в объект Картинка в платформе 1С:Предприятие.

Шаг 1. Отсечение заголовка метаданных

С помощью встроенной функции Найти() определим позицию первой запятой и отрежем префикс с типом содержимого:


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

Шаг 2. Очистка строки от служебных символов

При передаче графических данных через HTML или веб-сервисы в Base64-строке могут встречаться переносы строк, пробелы или символы табуляции. Из-за них функция Base64Значение() может завершиться ошибкой или вернуть Неопределено. Выполним очистку строки перед декодированием:


СтрокаBase64 = СтрЗаменить(СтрокаBase64, Символы.ПС, "");
СтрокаBase64 = СтрЗаменить(СтрокаBase64, Символы.ВК, "");
СтрокаBase64 = СтрЗаменить(СтрокаBase64, " ", "");

Шаг 3. Декодирование строки в ДвоичныеДанные и создание Картинки

Для преобразования закодированного текста в бинарный вид используем глобальную функцию Base64Значение(). Полученные ДвоичныеДанные передадим напрямую в конструктор объекта Картинка:


ДвоичныеДанныеКартинки = Base64Значение(СтрокаBase64);
Если ЗначениеЗаполнено(ДвоичныеДанныеКартинки) Тогда
    КартинкаОбъект = Новый Картинка(ДвоичныеДанныеКартинки);
КонецЕсли;

Оптимизация: работа без временных файлов

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

В платформе 1С:Предприятие 8 конструктор объекта Картинка умеет принимать объект ДвоичныеДанные напрямую. Запись во временный файл не требуется.

Сравним неоптимальный и правильный варианты кода:

Неоптимальный вариант (с использованием диска):


// Не рекомендуется: лишние операции ввода-вывода с диском
ДвоичныеДанныеКартинки = Base64Значение(СтрокаBase64);
ИмяФайла = ПолучитьИмяВременногоФайла();
ДвоичныеДанныеКартинки.Записать(ИмяФайла);
КартинкаОбъект = Новый Картинка(ИмяФайла);
УдалитьФайлы(ИмяФайла);

Оптимальный вариант (прямое создание):


// Рекомендуется: прямое создание объекта из двоичных данных в памяти
ДвоичныеДанныеКартинки = Base64Значение(СтрокаBase64);
КартинкаОбъект = Новый Картинка(ДвоичныеДанныеКартинки);

Вывод изображения в Табличный Документ

Разберем, как вывести полученное изображение в печатную форму или макет табличного документа (например, при разборе элементов из ФорматированныйДокумент):


// Извлекаем чистую Base64-строку
ПозицияЗапятой = Найти(Элемент.Картинка, ",");
СтрокаBase64 = Сред(Элемент.Картинка, ПозицияЗапятой + 1);

// Преобразуем в картинку
ДвоичныеДанныеКартинки = Base64Значение(СтрокаBase64);
КартинкаПечати = Новый Картинка(ДвоичныеДанныеКартинки);

// Присваиваем рисунку табличного документа
РисунокМакета = ОбластьМакета.Рисунки.ЛоготипОрганизации;
РисунокМакета.Картинка = КартинкаПечати;

Отображение изображения на управляемой форме

Посмотрим на особенности отображения изображения в тонком клиенте на управляемой форме. Элемент формы «Поле картинки» связывается со строковым реквизитом формы, содержащим URL временного хранилища.

Сформируем функцию для серверного контекста формы:


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

На стороне клиента достаточно присвоить полученный адрес реквизиту формы:


&НаКлиенте
Процедура ОтобразитьКартинкуНаФорме()
    ЭтаФорма.ПутьККартинке = ПолучитьАдресКартинкиИзBase64(СтрокаDataURL);
КонецПроцедуры

Сохранение в базу данных и определение формата

Если полученную картинку требуется записать в реквизит объекта (например, с типом ХранилищеЗначения), создавать объект Картинка не требуется. Достаточно обернуть ДвоичныеДанные напрямую:


ДвоичныеДанныеКартинки = Base64Значение(СтрокаBase64);

ОбъектСправочника = СсылкаНаЭлемент.ПолучитьОбъект();
ОбъектСправочника.ФайлКартинки = Новый ХранилищеЗначения(ДвоичныеДанныеКартинки, Новый СжатиеДанных(9));
ОбъектСправочника.Записать();

Если необходимо узнать расширение или формат загруженной картинки, воспользуемся методом Формат():


КартинкаОбъект = Новый Картинка(ДвоичныеДанныеКартинки);
ФорматКартинки = КартинкаОбъект.Формат(); // Возвращает системный формат (PNG, JPEG, GIF, BMP и т.д.)

Универсальная функция-помощник

Обобщим рассмотренную логику в виде готовой экспортируемой функции, которую можно добавить в общий модуль конфигурации:


// Преобразует строку формата Data URL или чистый Base64 в объект Картинка
// 
// Параметры:
//  ВходнаяСтрока - Строка - Данные картинки в формате Data URI или Base64
// 
// Возвращаемое значение:
//  Картинка, Неопределено - Объект картинка или Неопределено при ошибке декодирования
//
Функция ПреобразоватьBase64ВКартинку(Знач ВходнаяСтрока) Экспорт
    
    Если НЕ ЗначениеЗаполнено(ВходнаяСтрока) Тогда
        Возврат Неопределено;
    КонецЕсли;
    
    // Поиск разделителя заголовка
    ПозицияЗапятой = Найти(ВходнаяСтрока, ",");
    Если ПозицияЗапятой > 0 Тогда
        СтрокаBase64 = Сред(ВходнаяСтрока, ПозицияЗапятой + 1);
    Иначе
        СтрокаBase64 = ВходнаяСтрока;
    КонецЕсли;
    
    // Очистка от служебных символов
    СтрокаBase64 = СтрЗаменить(СтрокаBase64, Символы.ПС, "");
    СтрокаBase64 = СтрЗаменить(СтрокаBase64, Символы.ВК, "");
    СтрокаBase64 = СтрЗаменить(СтрокаBase64, " ", "");
    
    Попытка
        ДвоичныеДанныеКартинки = Base64Значение(СтрокаBase64);
        Если ЗначениеЗаполнено(ДвоичныеДанныеКартинки) Тогда
            Возврат Новый Картинка(ДвоичныеДанныеКартинки);
        КонецЕсли;
    Исключение
        ЗаписьЖурналаРегистрации("Декодирование Base64 картинки", 
            УровеньЖурналаРегистрации.Ошибка,,, ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
    КонецПопытки;
    
    Возврат Неопределено;
    
КонецФункции

Таким образом, мы рассмотрели универсальный и безопасный алгоритм преобразования текстовых строк Data URL в графические объекты 1С, изучили нюансы очистки служебных символов и способы корректного вывода изображений в печатные формы и на управляемый интерфейс.

← На главную