Рассмотрим распространенную техническую задачу: при обработке содержимого объекта ФорматированныйДокумент, выгрузок из HTML или интеграции с веб-сервисами графические данные передаются не в виде привычного файла, а в виде текстовой строки формата Data URI (например, data:image/png;base64,iVBORw0KGgoAAAANSU...). Для вывода такого изображения в табличный документ, макет или на управляемую форму его необходимо преобразовать в объект 1С Картинка.
Разберем по шагам структуру такой строки, универсальный метод очистки от заголовка метаданных, правильное декодирование и способы оптимизации работы с памятью без создания лишних файлов на диске.
Проанализируем структуру текстовой строки формата Data URI. Согласно спецификации RFC 2397, она состоит из нескольких основных элементов:
data:image/png, image/jpeg или image/gif;base64,Так как MIME-тип зависит от формата файла (PNG, JPEG, WebP, SVG), жестко отрезать фиксированное количество символов (например, первые 22 или 23 символа) не рекомендуется. Наиболее универсальное решение — искать первое вхождение запятой и отсекать всю левую часть строки.
Рассмотрим пошаговый процесс преобразования строки 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С, изучили нюансы очистки служебных символов и способы корректного вывода изображений в печатные формы и на управляемый интерфейс.