Разработка и Конфигурация · 11 мин
Как сохранить картинку в 1С программно
Как сохранить картинку в 1С программно: объект Картинка, метод Записать, хранение в хранилище значений, работа с двоичными данными и типичные ошибки разработчиков.
Во встроенном языке 1С работа с изображениями построена вокруг объекта Картинка и двоичных данных. Программное сохранение картинки требуется в самых разных сценариях: выгрузка фотографий товаров на сайт, экспорт штрихкодов и QR-кодов в файлы, сохранение подписей и печатей из справочников, формирование вложений для отправки по почте.
Ключевой метод — Записать() объекта Картинка, который принимает либо путь к файлу, либо поток. Однако на практике картинка чаще всего хранится не в файле, а в базе — в реквизите типа «Хранилище значения», поэтому полный цикл обычно включает извлечение данных из базы, преобразование и только потом запись на диск.
Важно учитывать контекст исполнения: на тонком клиенте без модального режима и на веб-клиенте прямая запись в произвольный путь недоступна, и приходится использовать асинхронные методы, временное хранилище и передачу данных между клиентом и сервером. Ниже разобраны рабочие варианты кода для типовых задач.
Объект Картинка и метод Записать
Базовый способ — создать объект Картинка из файла или из двоичных данных и записать его в нужное место. Конструктор объекта принимает путь к файлу, двоичные данные или поток:
// Загрузка из файла и сохранение в другой файл
Картинка = Новый Картинка("C:\Исходные\фото.bmp");
Картинка.Записать("C:\Результат\фото.png");
// Загрузка из двоичных данных
ДвоичныеДанные = Новый ДвоичныеДанные("C:\Исходные\фото.jpg");
Картинка = Новый Картинка(ДвоичныеДанные);
Картинка.Записать("C:\Результат\фото_копия.jpg");
Метод Записать() умеет определять формат по расширению файла, но надёжнее указывать формат явно вторым параметром, если требуется преобразование: Картинка.Записать("C:\out.png", ФорматКартинки.PNG). Поддерживаются распространённые форматы — PNG, JPEG, BMP, GIF и другие, набор зависит от версии платформы.
Обратите внимание: объект Картинка доступен как на сервере, так и на толстом клиенте. На тонком и веб-клиенте его возможности ограничены, поэтому файловые операции с изображениями принято выполнять в серверной процедуре.
Сохранение картинки из реквизита «Хранилище значения»
Наиболее частая практическая задача — выгрузить на диск изображение, которое хранится в базе, например фото товара в справочнике «Номенклатура» или логотип организации. В типовых конфигурациях такие данные лежат в реквизите типа ХранилищеЗначения, а внутри — либо объект Картинка, либо двоичные данные.
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.ФайлКартинки КАК ФайлКартинки
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| Номенклатура.Ссылка = &Ссылка";
Запрос.УстановитьПараметр("Ссылка", ТоварСсылка);
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() Тогда
Хранилище = Выборка.ФайлКартинки; // реквизит-ссылка на файл
// Получаем двоичные данные из хранилища значений
ДвоичныеДанные = Хранилище.ДанныеФайла.Получить(); // пример структуры
Если ТипЗнч(ДвоичныеДанные) = Тип("ДвоичныеДанные") Тогда
ДвоичныеДанные.Записать("C:\Выгрузка\фото_товара.jpg");
КонецЕсли;
КонецЕсли;
Структура хранения отличается между конфигурациями: в одних хранилище значений лежит прямо в реквизите объекта, в других — в отдельном справочнике присоединённых файлов или в регистре сведений. Перед написанием кода откройте конфигуратор и уточните, где физически лежат данные и что именно помещено в хранилище: объект Картинка или двоичные данные.
Если в хранилище сохранён именно объект Картинка, после Получить() вызывайте у результата метод Записать(). Если там двоичные данные — у них тоже есть метод Записать(ИмяФайла). Универсальная проверка типа через ТипЗнч() защитит от ошибки «Метод объекта не обнаружен».
- 1Определите в конфигураторе, где хранится изображение: реквизит объекта, справочник файлов или регистр сведений
- 2Получите значение хранилища методом Получить() и проверьте тип результата через ТипЗнч()
- 3Вызовите Записать() у объекта Картинка или у двоичных данных с указанием полного пути
- 4Проверьте, что файл создан и открывается в просмотрщике изображений
Сохранение картинки на клиенте и на сервере
В клиент-серверном режиме код, выполняемый на сервере, пишет файлы в файловую систему сервера — пользователь их не увидит. Если требуется отдать файл пользователю, типовая схема такая: на сервере картинка помещается во временное хранилище, на клиенте извлекается и сохраняется через диалог выбора файла.
&НаСервере
Функция ПоместитьКартинкуВоВременноеХранилище(ТоварСсылка)
ДвоичныеДанные = ПолучитьДвоичныеДанныеКартинки(ТоварСсылка);
Возврат ПоместитьВоВременноеХранилище(ДвоичныеДанные, УникальныйИдентификатор);
КонецФункции
&НаКлиенте
Процедура СохранитьКартинку(Команда)
Адрес = ПоместитьКартинкуВоВременноеХранилище(ТоварСсылка);
ПолучитьФайл(Адрес, "фото_товара.jpg", Истина);
КонецПроцедуры
Метод ПолучитьФайл() с третьим параметром Истина открывает диалог сохранения. В современных версиях платформы, где модальные вызовы запрещены, используют асинхронный вариант НачатьПолучениеФайла() с описанием оповещения. На веб-клиенте это единственный рабочий путь — прямой записи на диск пользователя там нет в принципе.
Обратная задача — загрузка картинки от пользователя в базу — решается методом НачатьПомещениеФайла(): файл попадает во временное хранилище, а серверная процедура забирает оттуда двоичные данные и складывает их в хранилище значений.
Как выбрать способ сохранения
Преобразование формата и изменение размера
Объект Картинка позволяет не только переписать файл, но и конвертировать формат и изменить размер. Это полезно, когда из базы выгружаются тяжёлые BMP или TIFF, а для сайта нужен компактный JPEG или PNG.
Картинка = Новый Картинка("C:\Исходные\фото.bmp");
// Изменение размера
Картинка = Картинка.ИзменитьРазмер(800, 600);
// Конвертация в PNG при записи
Картинка.Записать("C:\Результат\фото_800.png", ФорматКартинки.PNG);
Метод ИзменитьРазмер() не соблюдает пропорции автоматически: если передать произвольные ширину и высоту, изображение исказится. Чтобы сохранить пропорции, вычислите второй размер от исходного соотношения сторон, которое доступно через свойства Ширина() и Высота() (возвращают размеры в пикселях).
Имейте в виду ограничение: обработка изображений средствами платформы базовая. Сложные задачи — водяные знаки, обрезка по маске, тонкая настройка качества JPEG — обычно решают внешними компонентами или вызовом сторонних утилит через ЗапуститьПриложение().
При пакетной конвертации изображений для сайта выгоднее сначала выгрузить оригиналы из 1С в каталог, а ресайз и сжатие выполнить специализированным инструментом — это быстрее и даёт более предсказуемое качество, чем обработка встроенными средствами платформы.
Типичные ошибки и их диагностика
Чаще всего сохранение картинки ломается не в самом методе Записать(), а на этапе получения данных. Ошибка «Значение не является значением объектного типа» при вызове Получить() означает, что вы обратились не к реквизиту-хранилищу, а к строке или ссылке.
Вторая частая ситуация — пустой результат: реквизит с картинкой не заполнен у конкретного объекта, Получить() возвращает Неопределено, и следующий вызов падает. Всегда проверяйте результат на Неопределено перед записью.
Третья группа проблем — права доступа к файловой системе. Сервер 1С работает под своей учётной записью, и у неё может не быть прав на сетевой каталог или папку пользователя. Симптом — ошибка «Ошибка доступа к файлу» при внешне корректном пути.
Проверка результата и ограничения
После записи файла полезно убедиться, что результат корректен. Минимальная проверка — существование файла и ненулевой размер через объект Файл:
Файл = Новый Файл("C:\Результат\фото.png");
Если Файл.Существует() И Файл.Размер() > 0 Тогда
// файл записан
КонецЕсли;
Более строгая проверка — попытаться заново открыть записанный файл конструктором Новый Картинка(Путь): если данные повреждены или формат не распознан, платформа выдаст исключение уже на этапе проверки, а не у получателя файла.
Из ограничений стоит помнить: размер данных, передаваемых через временное хранилище между клиентом и сервером, влияет на производительность при больших изображениях; веб-клиент в некоторых браузерах накладывает свои ограничения на скачивание; а одновременная запись в один файл из нескольких сеансов приведёт к ошибке совместного доступа — для пакетных операций генерируйте уникальные имена файлов.
Как проверить результат
Файл существует, размер больше нуля
Файл отсутствует или имеет нулевой размер
Открывается в просмотрщике и через Новый Картинка без ошибок
Ошибка чтения формата, чёрный или пустой кадр
Файл появился там, где ожидает пользователь
Файл записан на сервер, а пользователь ищет его у себя
Частые вопросы
Как сохранить картинку из табличного документа?
Табличный документ напрямую в картинку не конвертируется штатными средствами. Практичные варианты: сохранить документ в PDF через ТабличныйДокумент.Записать(Путь, ТипФайлаТабличногоДокумента.PDF) и затем при необходимости конвертировать PDF в изображение внешними средствами.
Как узнать формат картинки, хранящейся в базе?
Если в хранилище лежит объект Картинка, формат доступен через свойство Формат(). Если хранятся двоичные данные, формат обычно зафиксирован в отдельном реквизите (расширение файла) либо определяется по сигнатуре первых байт данных.
Можно ли сохранить картинку без диалога, сразу в папку пользователя?
На тонком клиенте — да, если известен путь и разрешён доступ к файловой системе: используйте НачатьПолучениеФайла с явным именем файла. На веб-клиенте без диалога сохранить нельзя — браузер сам управляет скачиванием.
Почему после Записать файл не открывается?
Типичные причины: в хранилище лежали не изображение, а другие данные; файл записан не полностью из-за ошибки, перехваченной попыткой-исключением; либо расширение файла не соответствует реальному формату данных. Проверьте тип и размер данных до записи.
Как сохранить сразу много картинок одним архивом?
Выгрузите каждое изображение во временный каталог на сервере, затем упакуйте каталог объектом ЗаписьZipФайла и передайте готовый архив клиенту через временное хранилище. После отправки временные файлы удаляйте.
Что важно запомнить
Основной инструмент — метод Записать() объекта Картинка или двоичных данных. Изображения из базы сначала извлекаются из хранилища значений методом Получить() с проверкой типа и на Неопределено. Для передачи файла пользователю используют временное хранилище и ПолучитьФайл на клиенте, а на веб-клиенте — только асинхронные методы. Перед записью проверяйте права на каталог, после — существование и читаемость файла.