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

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

Как сохранить картинку в 1С программно

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

Во встроенном языке 1С работа с изображениями построена вокруг объекта Картинка и двоичных данных. Программное сохранение картинки требуется в самых разных сценариях: выгрузка фотографий товаров на сайт, экспорт штрихкодов и QR-кодов в файлы, сохранение подписей и печатей из справочников, формирование вложений для отправки по почте.

Ключевой метод — Записать() объекта Картинка, который принимает либо путь к файлу, либо поток. Однако на практике картинка чаще всего хранится не в файле, а в базе — в реквизите типа «Хранилище значения», поэтому полный цикл обычно включает извлечение данных из базы, преобразование и только потом запись на диск.

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

Объект Картинка и метод Записать

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

// Загрузка из файла и сохранение в другой файл

Картинка = Новый Картинка("C:\Исходные\фото.bmp");

Картинка.Записать("C:\Результат\фото.png");

// Загрузка из двоичных данных

ДвоичныеДанные = Новый ДвоичныеДанные("C:\Исходные\фото.jpg");

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

Картинка.Записать("C:\Результат\фото_копия.jpg");

Метод Записать() умеет определять формат по расширению файла, но надёжнее указывать формат явно вторым параметром, если требуется преобразование: Картинка.Записать("C:\out.png", ФорматКартинки.PNG). Поддерживаются распространённые форматы — PNG, JPEG, BMP, GIF и другие, набор зависит от версии платформы.

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

Сохранение картинки из реквизита «Хранилище значения»

Наиболее частая практическая задача — выгрузить на диск изображение, которое хранится в базе, например фото товара в справочнике «Номенклатура» или логотип организации. В типовых конфигурациях такие данные лежат в реквизите типа ХранилищеЗначения, а внутри — либо объект Картинка, либо двоичные данные.

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

Запрос.Текст =

"ВЫБРАТЬ

| Номенклатура.ФайлКартинки КАК ФайлКартинки

|ИЗ

| Справочник.Номенклатура КАК Номенклатура

|ГДЕ

| Номенклатура.Ссылка = &Ссылка";

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

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

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

Хранилище = Выборка.ФайлКартинки; // реквизит-ссылка на файл

// Получаем двоичные данные из хранилища значений

ДвоичныеДанные = Хранилище.ДанныеФайла.Получить(); // пример структуры

Если ТипЗнч(ДвоичныеДанные) = Тип("ДвоичныеДанные") Тогда

ДвоичныеДанные.Записать("C:\Выгрузка\фото_товара.jpg");

КонецЕсли;

КонецЕсли;

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

Если в хранилище сохранён именно объект Картинка, после Получить() вызывайте у результата метод Записать(). Если там двоичные данные — у них тоже есть метод Записать(ИмяФайла). Универсальная проверка типа через ТипЗнч() защитит от ошибки «Метод объекта не обнаружен».

Порядок выгрузки картинки из базы в файл
  1. 1
    Определите в конфигураторе, где хранится изображение: реквизит объекта, справочник файлов или регистр сведений
  2. 2
    Получите значение хранилища методом Получить() и проверьте тип результата через ТипЗнч()
  3. 3
    Вызовите Записать() у объекта Картинка или у двоичных данных с указанием полного пути
  4. 4
    Проверьте, что файл создан и открывается в просмотрщике изображений

Сохранение картинки на клиенте и на сервере

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

&НаСервере

Функция ПоместитьКартинкуВоВременноеХранилище(ТоварСсылка)

ДвоичныеДанные = ПолучитьДвоичныеДанныеКартинки(ТоварСсылка);

Возврат ПоместитьВоВременноеХранилище(ДвоичныеДанные, УникальныйИдентификатор);

КонецФункции

&НаКлиенте

Процедура СохранитьКартинку(Команда)

Адрес = ПоместитьКартинкуВоВременноеХранилище(ТоварСсылка);

ПолучитьФайл(Адрес, "фото_товара.jpg", Истина);

КонецПроцедуры

Метод ПолучитьФайл() с третьим параметром Истина открывает диалог сохранения. В современных версиях платформы, где модальные вызовы запрещены, используют асинхронный вариант НачатьПолучениеФайла() с описанием оповещения. На веб-клиенте это единственный рабочий путь — прямой записи на диск пользователя там нет в принципе.

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

Маршрут решения

Как выбрать способ сохранения

Файл нужен на сервере для дальнейшей обработки или обменаВыполняйте Записать() прямо в серверной процедуре
Файл должен получить пользователь на свой компьютерПоместите данные во временное хранилище на сервере и заберите через ПолучитьФайл на клиенте
Работа идёт на веб-клиентеИспользуйте только асинхронные методы НачатьПолучениеФайла и НачатьПомещениеФайла
Нужна пакетная выгрузка множества картинокФормируйте файлы на сервере в каталог и при необходимости упаковывайте в ZIP-архив

Преобразование формата и изменение размера

Объект Картинка позволяет не только переписать файл, но и конвертировать формат и изменить размер. Это полезно, когда из базы выгружаются тяжёлые BMP или TIFF, а для сайта нужен компактный JPEG или PNG.

Картинка = Новый Картинка("C:\Исходные\фото.bmp");

// Изменение размера

Картинка = Картинка.ИзменитьРазмер(800, 600);

// Конвертация в PNG при записи

Картинка.Записать("C:\Результат\фото_800.png", ФорматКартинки.PNG);

Метод ИзменитьРазмер() не соблюдает пропорции автоматически: если передать произвольные ширину и высоту, изображение исказится. Чтобы сохранить пропорции, вычислите второй размер от исходного соотношения сторон, которое доступно через свойства Ширина() и Высота() (возвращают размеры в пикселях).

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

При пакетной конвертации изображений для сайта выгоднее сначала выгрузить оригиналы из 1С в каталог, а ресайз и сжатие выполнить специализированным инструментом — это быстрее и даёт более предсказуемое качество, чем обработка встроенными средствами платформы.
ПЗ
Практическое замечание

Типичные ошибки и их диагностика

Чаще всего сохранение картинки ломается не в самом методе Записать(), а на этапе получения данных. Ошибка «Значение не является значением объектного типа» при вызове Получить() означает, что вы обратились не к реквизиту-хранилищу, а к строке или ссылке.

Вторая частая ситуация — пустой результат: реквизит с картинкой не заполнен у конкретного объекта, Получить() возвращает Неопределено, и следующий вызов падает. Всегда проверяйте результат на Неопределено перед записью.

Третья группа проблем — права доступа к файловой системе. Сервер 1С работает под своей учётной записью, и у неё может не быть прав на сетевой каталог или папку пользователя. Симптом — ошибка «Ошибка доступа к файлу» при внешне корректном пути.

Типичные ошибки
01
Вызов Записать() без проверки, что Получить() вернул данные — падение на пустых реквизитах
02
Запись файла на сервере с ожиданием, что он появится у пользователя — данные остаются на диске сервера
03
Использование модального ПолучитьФайл в конфигурации с запрещёнными модальными вызовами — код не компилируется
04
Передача пути без каталога или с несуществующим каталогом — метод Записать не создаёт промежуточные папки
05
Искажение пропорций при ИзменитьРазмер из-за произвольных ширины и высоты

Проверка результата и ограничения

После записи файла полезно убедиться, что результат корректен. Минимальная проверка — существование файла и ненулевой размер через объект Файл:

Файл = Новый Файл("C:\Результат\фото.png");

Если Файл.Существует() И Файл.Размер() > 0 Тогда

// файл записан

КонецЕсли;

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

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

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

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

Файл на диске
Норма

Файл существует, размер больше нуля

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

Файл отсутствует или имеет нулевой размер

Содержимое файла
Норма

Открывается в просмотрщике и через Новый Картинка без ошибок

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

Ошибка чтения формата, чёрный или пустой кадр

Место записи
Норма

Файл появился там, где ожидает пользователь

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

Файл записан на сервер, а пользователь ищет его у себя

Частые вопросы

Как сохранить картинку из табличного документа?

Табличный документ напрямую в картинку не конвертируется штатными средствами. Практичные варианты: сохранить документ в PDF через ТабличныйДокумент.Записать(Путь, ТипФайлаТабличногоДокумента.PDF) и затем при необходимости конвертировать PDF в изображение внешними средствами.

Как узнать формат картинки, хранящейся в базе?

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

Можно ли сохранить картинку без диалога, сразу в папку пользователя?

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

Почему после Записать файл не открывается?

Типичные причины: в хранилище лежали не изображение, а другие данные; файл записан не полностью из-за ошибки, перехваченной попыткой-исключением; либо расширение файла не соответствует реальному формату данных. Проверьте тип и размер данных до записи.

Как сохранить сразу много картинок одним архивом?

Выгрузите каждое изображение во временный каталог на сервере, затем упакуйте каталог объектом ЗаписьZipФайла и передайте готовый архив клиенту через временное хранилище. После отправки временные файлы удаляйте.

Итог

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

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