Работа с внешними сервисами через API практически всегда подразумевает обмен данными в формате Base64. Это стандартный способ передачи бинарных данных (например, изображений товаров) внутри текстовых пакетов JSON или XML. Однако программисты 1С часто сталкиваются с ситуацией: код выполняется без ошибок, файл на диске создается, но его размер равен 0 байт, либо объект Картинка остается пустым. Разберем по шагам, почему это происходит и как гарантированно получить валидное изображение.
Рассмотрим типичный сценарий: мы получаем строку из стороннего сервиса и пытаемся преобразовать ее в картинку. На первый взгляд код выглядит логичным, мы пытаемся очистить строку от переносов строк и лишних пробелов перед конвертацией:
Бэйз64Строка = РазобранныйМассивТоваров[Индекс3];
Бэйз64Строка = СтрЗаменить(Бэйз64Строка, Символы.ВК, "");
Бэйз64Строка = СтрЗаменить(Бэйз64Строка, Символы.ПС, "");
Бэйз64Строка = СтрЗаменить(Бэйз64Строка, "\n", "");
ИзображениеНоменклатуры = Новый Картинка(Base64Значение(СокрЛП(Бэйз64Строка)));
ПутьКФайлу = "C:\temp\NomImWS.jpg";
Попытка
ИзображениеНоменклатуры.Записать(ПутьКФайлу);
Исключение
Сообщить(ОписаниеОшибки());
КонецПопытки;
Проблема заключается в том, что метод Base64Значение() крайне чувствителен к любым посторонним символам в строке. Если онлайн-декодеры в браузере умеют "прощать" ошибки форматирования, то встроенные механизмы платформы 1С требуют идеально чистую последовательность символов алфавита Base64.
Проанализируем структуру строки, которую прислал сервис. Часто в JSON-ответах символы прямого слэша / (который является частью алфавита Base64) заменяются на экранированную последовательность \/.
Для JSON это стандартное поведение, но для функции Base64Значение символ обратного слэша \ является мусором. Именно из-за него алгоритм декодирования прерывается, возвращая пустой результат.
Решение: Нам необходимо обязательно удалить все символы обратного слэша из полученной строки перед обработкой.
// Удаляем символы экранирования, которые часто встречаются в JSON
Бэйз64Строка = СтрЗаменить(Бэйз64Строка, "\", "");
Помимо экранирования слэшей, существует еще несколько критических моментов, которые мы должны проверить, если картинка все равно не сохраняется:
data:image/jpeg;base64,. Если этот заголовок попадет в метод Base64Значение, картинка будет пустой. Нам нужно найти позицию первой запятой и взять только ту часть строки, которая идет после нее.СокрЛП их не удаляет.=. Если сервис "обрезал" эти символы, 1С может не распознать строку.Проанализируем более совершенный подход к обработке данных. Вместо использования устаревшего метода Base64Значение, в современной платформе (начиная с 8.3.10) рекомендуется работать через ДвоичныеДанные. Это дает больше контроля над процессом.
// Функция для безопасного получения картинки из Base64
Функция ПолучитьКартинкуИзBase64(Знач ВходящаяСтрока)
// 1. Очистка от служебных символов JSON и переносов
ЧистаяСтрока = СтрЗаменить(ВходящаяСтрока, "\", "");
ЧистаяСтрока = СтрЗаменить(ЧистаяСтрока, Символы.ПС, "");
ЧистаяСтрока = СтрЗаменить(ЧистаяСтрока, Символы.ВК, "");
ЧистаяСтрока = СтрЗаменить(ЧистаяСтрока, " ", ""); // Удаляем обычные пробелы
// 2. Проверка на наличие префикса "data:..."
ПозицияЗапятой = Найти(ЧистаяСтрока, ",");
Если ПозицияЗапятой > 0 Тогда
ЧистаяСтрока = Сред(ЧистаяСтрока, ПозицияЗапятой + 1);
КонецЕсли;
Попытка
// Используем современный метод преобразования
ДвоичныеДанные = Base64СтрокаВДвоичныеДанные(ЧистаяСтрока);
// Проверяем, что данные не пустые
Если ДвоичныеДанные.Размер() > 0 Тогда
Возврат Новый Картинка(ДвоичныеДанные);
Иначе
Возврат Неопределено;
КонецЕсли;
Исключение
ЗаписатьЛогОшибок(ОписаниеОшибки());
Возврат Неопределено;
КонецПопытки;
КонецФункции
Важно помнить, где именно выполняется ваш код. Если вы работаете в Тонком клиенте, прямой вызов Картинка.Записать(Путь) может столкнуться с ограничениями прав доступа к файловой системе сервера или клиента.
Рекомендуемый порядок действий:
ДвоичныеДанные на стороне сервера.ДвоичныеДанные на клиент (они отлично сериализуются).ДвоичныеДанные.Записать(ПутьКФайлу). Это работает быстрее и надежнее, чем запись через объект Картинка.Если вы получаете картинку нулевого размера из Base64, первым делом выполните СтрЗаменить(Бэйз64Строка, "\", ""). В 90% случаев при интеграции с веб-сервисами проблема кроется именно в этом. Вторым шагом проверьте строку на наличие префикса data:image/...;base64, и удалите его. Используйте современные методы Base64СтрокаВДвоичныеДанные вместо Base64Значение для лучшей диагностики ошибок.