К статье
Практический материал

Разработка и Конфигурация · 10 мин

1С: как получить двоичные данные картинки

Как в 1С получить двоичные данные картинки: из файла, реквизита хранилища значений, справочника и временного хранилища. Примеры кода, ошибки и проверка результата.

Во встроенном языке 1С картинка может существовать в нескольких видах: как объект Картинка, как файл на диске, как значение в реквизите типа ХранилищеЗначения и как объект ДвоичныеДанные. Задача «получить двоичные данные картинки» чаще всего возникает при обмене с веб-сервисами, отправке изображений по HTTP, конвертации в Base64 или при переносе файлов между базами.

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

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

Получение двоичных данных из файла на диске

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

ДвоичныеДанныеКартинки = Новый ДвоичныеДанные("C:\Images\photo.jpg");

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

Частая ситуация: пользователь выбирает файл через диалог, а обработка выполняется на сервере. В этом случае напрямую читать файл на сервере нельзя — сначала файл помещают во временное хранилище с клиента, а на сервере извлекают двоичные данные из хранилища:

// На клиенте

НачатьПомещениеФайла(Новый ОписаниеОповещения("ПослеПомещения", ЭтотОбъект),

АдресХранилища, , Истина, УникальныйИдентификатор);

// На сервере

ДвоичныеДанныеКартинки = ПолучитьИзВременногоХранилища(АдресХранилища);

Извлечение двоичных данных из реквизита ХранилищеЗначения

В типовых конфигурациях изображения обычно хранятся в реквизитах типа ХранилищеЗначения — например, в присоединённых файлах или в специальных реквизитах справочников. Чтобы получить двоичные данные, нужно вызвать метод Получить() у значения хранилища:

Запрос = Новый Запрос;

Запрос.Текст = "ВЫБРАТЬ ФайлКартинки ИЗ Справочник.Товары ГДЕ Ссылка = &Ссылка";

Запрос.УстановитьПараметр("Ссылка", ТоварСсылка);

Выборка = Запрос.Выполнить().Выбрать();

Если Выборка.Следующий() Тогда

ДвоичныеДанныеКартинки = Выборка.ФайлКартинки.Получить();

КонецЕсли;

Метод Получить() возвращает то, что было помещено в хранилище. Если туда сохраняли именно ДвоичныеДанные — вернутся двоичные данные. Если сохраняли объект Картинка — вернётся объект картинки, и его придётся преобразовывать отдельно (об этом ниже). Если хранилище пустое, метод вернёт Неопределено — это обязательно нужно проверять перед дальнейшей обработкой.

В конфигурациях с БСП (Библиотека стандартных подсистем) присоединённые файлы хранятся в справочниках вида «ТоварыПрисоединенныеФайлы», и для их чтения есть готовая функция РаботаСФайлами.ДвоичныеДанныеФайла(ПрисоединенныйФайл). Она учитывает тома хранения файлов и возвращает двоичные данные независимо от того, лежит файл в базе или в каталоге на диске.

Преобразование объекта Картинка в двоичные данные

Если у вас уже есть объект типа Картинка (например, полученный из реквизита формы или созданный программно), прямого метода «вернуть двоичные данные» у него нет. Стандартный приём — записать картинку в поток и прочитать данные из потока:

Поток = Новый ПотокВПамяти();

КартинкаОбъект.Записать(Поток);

ДвоичныеДанныеКартинки = Поток.ЗакрытьИПолучитьДвоичныеДанные();

Альтернатива без потоков — записать картинку во временный файл и прочитать его конструктором Новый ДвоичныеДанные. Этот способ проще, но медленнее и оставляет временные файлы, поэтому в массовых обработках предпочтителен вариант с потоком.

Обратный путь — из двоичных данных получить объект Картинка для отображения на форме — выполняется конструктором:

КартинкаОбъект = Новый Картинка(ДвоичныеДанныеКартинки);
bsl
Поток = Новый ПотокВПамяти();
КартинкаОбъект.Записать(Поток);
ДвоичныеДанные = Поток.ЗакрытьИПолучитьДвоичныеДанные();

Кодирование в Base64 для обмена и HTTP

Двоичные данные нельзя напрямую вставить в JSON или XML — их предварительно кодируют в Base64. В 1С для этого есть функции Base64Строка() и обратная Base64Значение():

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

// Передача в JSON, HTTP-запрос, веб-сервис...

// Обратное декодирование:

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

Учтите, что Base64 увеличивает объём данных примерно на треть. При передаче больших изображений это может упираться в ограничения веб-сервиса или HTTP-клиента на размер тела запроса. Если передаёте картинки пакетами, контролируйте итоговый размер запроса и при необходимости сжимайте изображение до кодирования.

Если принимающая сторона — сторонний API, уточните в его документации формат: иногда требуется строка с префиксом вида data:image/jpeg;base64,, иногда «чистый» Base64 без префикса. Несовпадение формата — частая причина того, что картинка «не открывается» на другой стороне.

Порядок действий для отправки картинки по HTTP
  1. 1
    Получите двоичные данные: из файла, хранилища значений или присоединённого файла
  2. 2
    Проверьте, что данные не Неопределено и размер больше нуля
  3. 3
    Закодируйте данные в Base64 функцией Base64Строка()
  4. 4
    Сформируйте JSON или тело запроса по документации API
  5. 5
    Выполните HTTP-запрос и проверьте код ответа
  6. 6
    При ошибке сохраните тело ответа для анализа

Отображение картинки на форме через адрес хранилища

Обратная задача встречается не реже: двоичные данные есть, и их нужно показать пользователю в элементе формы. Для реквизита формы типа «Строка» с видом «Поле картинки» данные передаются через адрес временного хранилища:

// Серверная процедура

АдресКартинки = ПоместитьВоВременноеХранилище(ДвоичныеДанныеКартинки,

УникальныйИдентификатор);

Второй параметр — уникальный идентификатор формы — важен: он привязывает данные хранилища к времени жизни формы. Без него данные удалятся после завершения серверного вызова, и картинка на форме не отобразится либо пропадёт при следующем обращении к серверу.

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

Проверка результата и типичные ошибки

После получения двоичных данных полезно убедиться, что они корректны. Минимальные проверки: значение не равно Неопределено, размер больше нуля, а при необходимости — что по сигнатуре (первым байтам) файл действительно является изображением нужного формата.

Контрольные точки

Как проверить результат

Значение после Получить() или чтения файла
Норма

Тип ДвоичныеДанные, размер больше нуля

Тревожный признак

Неопределено или размер 0 — хранилище пустое или файл не прочитан

Картинка на форме
Норма

Изображение отображается сразу после серверного вызова

Тревожный признак

Пустое поле — адрес хранилища не привязан к УникальныйИдентификатор

Base64-строка
Норма

Декодируется обратно в файл, который открывается просмотрщиком

Тревожный признак

Ошибка декодирования — строка обрезана или содержит лишний префикс

Типичные ошибки
01
Чтение файла с диска на сервере, когда файл выбран на клиенте — сервер не видит клиентский диск, нужно помещение во временное хранилище
02
Отсутствие проверки на Неопределено после Получить() — падение кода на пустом хранилище
03
Помещение данных во временное хранилище без УникальныйИдентификатор формы — картинка пропадает после первого серверного вызова
04
Передача Base64 без учёта формата API — приёмная сторона ожидает префикс data:image/... или, наоборот, чистую строку
05
Попытка вызвать Получить() у хранилища значений на клиенте — метод доступен только на сервере

FAQ

Как узнать размер двоичных данных картинки?

Вызовите метод Размер() у объекта двоичных данных — он вернёт количество байт. Это удобно для проверки, что данные не пустые, и для контроля лимитов при передаче по HTTP.

Можно ли получить двоичные данные картинки из макета конфигурации?

Да. Получите макет через ПолучитьОбщийМакет("ИмяМакета") — для макета типа «Картинка» вернётся объект Картинка. Далее запишите его в поток в памяти и получите двоичные данные, как описано в соответствующем разделе.

Почему ПолучитьИзВременногоХранилища возвращает Неопределено?

Чаще всего данные уже удалены: либо истёк срок жизни хранилища, не привязанного к форме, либо адрес был сформирован в другом сеансе. Проверьте, что адрес получен в текущем сеансе и при помещении передавался УникальныйИдентификатор формы.

Как сохранить двоичные данные обратно в файл на диск?

Используйте метод Записать("Путь\К\Файлу.jpg") у объекта двоичных данных. Убедитесь, что каталог существует и у процесса есть права на запись — иначе получите ошибку без создания файла.

Чем отличается Картинка от ДвоичныеДанные в 1С?

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

Можно ли сжать картинку средствами 1С перед передачей?

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

Итог

Что важно запомнить

Двоичные данные картинки получают из файла конструктором Новый ДвоичныеДанные(), из реквизита методом Получить() на сервере, из объекта Картинка — через поток в памяти. Для обмена данные кодируют в Base64, для показа на форме — помещают во временное хранилище с привязкой к УникальныйИдентификатор. Всегда проверяйте результат на Неопределено и нулевой размер.