Разработка мобильных приложений на платформе 1С:Предприятие часто сопряжена с необходимостью оперативной передачи мультимедийных данных, таких как фотографии товаров, отчеты со складов или снимки документов, в центральную информационную базу. Основным инструментом взаимодействия в таких случаях выступают HTTPСервисы. Однако при работе с изображениями возникают нюансы, связанные с объемом данных, ограничениями веб-серверов и производительностью мобильного устройства.
В этой статье мы подробно разберем, как захватить изображение с камеры смартфона и доставить его в рабочую базу в целости и сохранности, используя оптимальные технические решения.
Проанализируем наиболее эффективный с точки зрения объема трафика способ — передачу картинки как набора двоичных данных. Этот метод позволяет не тратить ресурсы на кодирование в Base64, которое увеличивает размер пакета примерно на 30%.
На стороне мобильного приложения:
Сначала мы получаем снимок, используя СредстваМультимедиа, затем извлекаем двоичные данные и помещаем их в тело POST-запроса.
// 1. Делаем фотоснимок
Настройки = Новый НастройкиЛокальногоУстройства;
Фото = СредстваМультимедиа.СделатьФотоснимок(ТипКамерыУстройства.Задняя, Настройки, 90);
Если Фото <> Неопределено Тогда
ДвоичныеДанныеКартинки = Фото.ПолучитьДвоичныеДанные();
// 2. Формируем HTTP-запрос
Соединение = Новый HTTPСоединение("адрес_сервера", , "логин", "пароль");
Запрос = Новый HTTPЗапрос("/ваша_база/hs/MyService/v1/upload");
// 3. Устанавливаем двоичные данные в тело запроса
Запрос.УстановитьТелоИзДвоичныхДанных(ДвоичныеДанныеКартинки);
Запрос.Заголовки.Вставить("Content-Type", "image/jpeg");
Ответ = Соединение.ОтправитьДляОбработки(Запрос);
КонецЕсли;
На стороне основной базы (HTTP-сервис):
В методе POST нашего сервиса мы считываем данные напрямую из запроса.
Функция UploadImage(Запрос)
// Получаем двоичные данные из тела HTTP-запроса
ДанныеКартинки = Запрос.ПолучитьТелоКакДвоичныеДанные();
// Далее можно сохранить в справочник или файл
НоваяКартинка = Справочники.Файлы.СоздатьЭлемент();
НоваяКартинка.Наименование = "Фото_из_МП_" + Формат(ТекущаяДата(), "ДФ=yyyyMMddHHmmss");
НоваяКартинка.ДанныеФайла = Новый ХранилищеЗначения(ДанныеКартинки);
НоваяКартинка.Записать();
Возврат Новый HTTPСервисОтвет(200);
КонецФункции
Выясним ситуацию, когда вместе с картинкой нужно передать дополнительные метаданные: ID документа, комментарий или координаты GPS. В этом случае удобно использовать JSON, а саму картинку преобразовать в строку Base64.
Рассмотрим по шагам реализацию этого подхода:
ДвоичныеДанные фотографии.Base64Строка().Структура и сериализуем в JSON.
ДанныеИзображения = Base64Строка(Фото.ПолучитьДвоичныеДанные());
ДанныеПакета = Новый Структура;
ДанныеПакета.Вставить("ИмяФайла", "photo.jpg");
ДанныеПакета.Вставить("Данные", ДанныеИзображения);
ДанныеПакета.Вставить("ИдентификаторОбъекта", "УИД_ВАШЕГО_ДОКУМЕНТА");
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJSON, ДанныеПакета);
СтрокаJSON = ЗаписьJSON.Закрыть();
Запрос.УстановитьТелоИзСтроки(СтрокаJSON);
Важное замечание: Передачу такого объема данных следует выполнять только через POST запрос. При использовании GET запросов строка Base64 будет обрезана, так как длина URL ограничена веб-серверами.
Если мобильный интернет нестабилен, проанализируем возможность предварительного сжатия данных. Платформа позволяет использовать ХранилищеЗначения с параметром СжатиеДанных. Это особенно полезно при пакетной передаче данных.
&НаСервереБезКонтекста
Функция ПодготовитьСжатыйПакет(Данные)
// Сжимаем данные с максимальной степенью 9
СжатыйПакет = Новый ХранилищеЗначения(Данные, Новый СжатиеДанных(9));
// Для передачи через HTTP сериализуем ХранилищеЗначения в XML или JSON
// (см. пример 13 в обсуждении форума)
Возврат СжатыйПакет;
КонецФункции
Часто программисты сталкиваются с тем, что код написан верно, но сервер возвращает ошибку 404 или 413. Разберем причину: по умолчанию IIS (Internet Information Services) ограничивает размер загружаемых данных (обычно до 30 Мб, но иногда лимиты могут быть и жестче).
Чтобы разрешить передачу «тяжелых» фотографий, необходимо отредактировать файл web.config на сервере, где опубликована база:
<system.webServer>
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="100000000" />
</requestFiltering>
</security>
</system.webServer>
Значение maxAllowedContentLength указано в байтах. В данном примере мы увеличили лимит до ~100 Мб.
Современные камеры смартфонов делают снимки разрешением 12–50 Мп. Передавать 10-мегабайтное фото для того, чтобы просто прикрепить его к акту осмотра, нецелесообразно. Мы рекомендуем выполнять ресайз (изменение размера) на стороне мобильного приложения.
Используйте объект Картинка для преобразования:
Картинка из полученных двоичных данных.JPEG с качеством 70-80%. Это уменьшит вес файла в десятки раз без потери читаемости.Поскольку передача файлов — операция длительная, разберем, как сделать работу пользователя комфортной:
ФоновоеЗадание, которое будет пытаться отправить данные.SQL. Используйте механизм «Тома хранения файлов», чтобы фотографии хранились на диске сервера, сохраняя базу компактной и быстрой.Следуя этим шагам, мы создадим надежный и быстрый механизм обмена медиафайлами между мобильными устройствами и центральной системой 1С.