При разработке мобильных и веб-приложений на платформе 1С:Предприятие 8.3 разработчики часто сталкиваются с проблемой производительности при работе с медиафайлами. Современные смартфоны делают снимки высокого разрешения, размер которых может достигать 15–20 Мб на один кадр. Если пользователь прикрепляет несколько таких фотографий к документу или элементу справочника, открытие формы превращается в мучительное ожидание, а база данных (особенно файловая) стремительно разрастается до критических размеров.
В этой статье мы подробно разберем, как правильно организовать хранение тяжелых изображений, сравним использование ХранилищаЗначения и дисковой подсистемы, рассмотрим механизмы программного сжатия картинок средствами 1С и изучим передовые методы статического кэширования файлов через веб-сервер.
Рассмотрим две базовые стратегии хранения бинарных данных в экосистеме 1С и проанализируем их влияние на производительность системы.
Вариант 1. Хранение в базе данных (ХранилищеЗначения)
При таком подходе файлы преобразуются в двоичные данные и записываются непосредственно в таблицы СУБД (или файл 1CD в случае файлового варианта).
.dt) или тестировании и исправлении (ТиИ) картинки переносятся автоматически. Нет риска потерять связь между карточкой в 1С и физическим файлом.Вариант 2. Хранение файлов на диске (в томах)
В базе данных сохраняется только текстовая ссылка (путь к файлу) или уникальный идентификатор, а сами файлы размещаются в выделенном каталоге на сервере или в сетевом хранилище.
.dt файлы не включаются в архив автоматически.Выясним, как нивелировать недостатки дискового хранения. Проанализируем простое правило: никогда не храните абсолютные пути к файлам в базе данных. Достаточно хранить относительный путь, а базовый каталог (том хранения) записывать в константу. Еще более надежный способ — использовать уникальный идентификатор (GUID) объекта 1С в качестве имени файла на диске:
ИмяФайла = Строка(СсылкаНаОбъект.УникальныйИдентификатор()) + ".jpg";
ПутьКФайлу = ПутьКТомуХранения + "\" + ИмяФайла;
В этом случае при выгрузке и загрузке информационной базы связь между объектами и файлами никогда не нарушится, так как GUID объекта остается неизменным.
Если пользователь загружает снимок чека или накладной размером 16 Мб по мобильному интернету, ни один способ хранения не обеспечит быструю работу. Передача такого объема данных по сети неизбежно вызовет задержку. Нам необходимо уменьшить размер файла до разумных пределов (150–300 Кб), сохранив при этом читаемость текста.
Разберем, как выполнить оптимизацию прямо в коде 1С без использования сторонних утилит.
Начиная с версии платформы 1С:Предприятие 8.3.14, разработчикам доступен мощный встроенный объект ОбрабатываемаяКартинка. Он позволяет программно изменять разрешение, формат и качество сжатия на стороне сервера или клиента.
Рассмотрим пример кода, который уменьшает разрешение исходного снимка до формата HD (1280x720 пикселей) и сохраняет его в JPEG с качеством 70%, что идеально подходит для документов и чеков:
&НаСервере
Функция СжатьИзображение(ДвоичныеДанныеИсточника) Экспорт
// Инициализируем обрабатываемую картинку из исходных двоичных данных
КартинкаОбъект = Новый ОбрабатываемаяКартинка(ДвоичныеДанныеИсточника);
// Определяем новые размеры с сохранением пропорций
Ширина = КартинкаОбъект.Ширина();
Высота = КартинкаОбъект.Высота();
МаксимальныйРазмер = 1280; // Ограничиваем большую сторону
Если Ширина > МаксимальныйРазмер Или Высота > МаксимальныйРазмер Тогда
КартинкаОбъект.УстановитьМаксимальныйРазмер(МаксимальныйРазмер, МаксимальныйРазмер);
КонецЕсли;
// Задаем параметры сжатия для формата JPEG
ПараметрыЗаписи = Новый ПараметрыЗаписиКартинки;
ПараметрыЗаписи.Формат = ФорматКартинки.JPEG;
ПараметрыЗаписи.Качество = 70; // 70% обеспечивает отличную читаемость текста и малый вес
// Получаем оптимизированные двоичные данные
СжатыеДанные = КартинкаОбъект.ПолучитьДвоичныеДанные(ПараметрыЗаписи);
Возврат СжатыеДанные;
КонецФункции
Применение этого алгоритма уменьшает размер файла с 16 Мб до 100–250 Кб. Скорость передачи файла по мобильной сети возрастает в 50–100 раз!
Зачем сначала получать огромный файл на телефоне, тратить ресурсы мобильного устройства на его обработку, а потом сжимать? Правильнее ограничить разрешение снимка непосредственно в момент вызова камеры смартфона.
Для этого при работе с мобильным клиентом мы можем использовать свойства объекта ПараметрыПолученияСнимка:
&НаКлиенте
Процедура СделатьСнимокСКамеры()
#Если МобильныйКлиент Тогда
ПараметрыСъемки = Новый ПараметрыПолученияСнимка;
ПараметрыСъемки.Разрешение = РазрешениеСнимка.Среднее; // Исключает создание 16 Мб файлов
ПараметрыСъемки.Источник = ИсточникИзображения.Камера;
ОписаниеОповещения = Новый ОписаниеОповещения("ПослеСъемки", ЭтотОбъект);
СредстваМультимедиа.СделатьСнимок(ПараметрыСъемки, ОписаниеОповещения);
#КонецЕсли
КонецПроцедуры
&НаКлиенте
Процедура ПослеСъемки(Результат, ДополнительныеПараметры) Экспорт
Если Результат = Неопределено Тогда
Возврат; // Пользователь отменил съемку
КонецЕсли;
// Результат содержит двоичные данные уже оптимизированного снимка
СохранитьСнимокНаСервере(Результат.ПолучитьДвоичныеДанные());
КонецПроцедуры
Если вы разрабатываете конфигурацию на базе БСП (Библиотека стандартных подсистем), вам не нужно изобретать велосипед для работы с файлами. В составе БСП есть подсистема «Работа с файлами».
Она предоставляет готовые механизмы:
Рассмотрим классическую схему вывода картинок на форму: веб-клиент делает запрос к серверу 1С, сервер 1С обращается к СУБД или диску, помещает картинку во временное хранилище, передает двоичные данные веб-серверу (IIS/Apache), а тот отправляет их в браузер. Это длинная цепочка, нагружающая сервер 1С.
Проанализируем альтернативное архитектурное решение:
C:\inetpub\wwwroot\static_images становится доступен извне по адресу http://имя_сервера/images/."invoice_8812.jpg").Строка, связанный с полем картинки или полем HTML-документа. В этот реквизит мы помещаем прямую HTTP-ссылку на статический файл: "http://имя_сервера/images/invoice_8812.jpg".Почему это работает быстрее?
При открытии формы браузер пользователя отправляет запрос на получение картинки напрямую веб-серверу (IIS/Apache). Веб-сервер отдает статический файл из файловой системы мгновенно, вообще не задействуя рабочий процесс 1С (rphost) и СУБД. Нагрузка на сервер 1С падает до нуля, а скорость отрисовки интерфейса возрастает многократно.
Использование прямых HTTP-ссылок решает еще одну важнейшую задачу — кэширование картинок на стороне клиента без написания сложного программного кода.
В настройках вашего веб-сервера (IIS или Apache) для папки со статическими изображениями необходимо включить HTTP-заголовок Cache-Control со значением, например, max-age=31536000 (хранить кэш 1 год).
Как только браузер пользователя один раз загрузит фотографию чека или товара, он сохранит ее в свой локальный кэш. При повторном открытии этой формы в веб-клиенте изображение отобразится мгновенно из локальной памяти устройства, без единого сетевого запроса к серверу!
Подведем итог нашего анализа и сформируем золотые правила для работы с изображениями в 1С:
ОбрабатываемаяКартинка для сжатия любых входящих фото до разрешения не более 1280x720 пикселей.