СредстваМультимедиа.ПоддерживаетсяСканированиеДокументов

Методы · DocumentScanningSupported

Определяет, поддерживается ли сканирование документов.

Синтаксис

ПоддерживаетсяСканированиеДокументов()
Полное описание, параметры и ограничения

СредстваМультимедиа.ПоддерживаетсяСканированиеДокументов (MultimediaTools.DocumentScanningSupported)

СредстваМультимедиа (MultimediaTools)

ПоддерживаетсяСканированиеДокументов (DocumentScanningSupported)

Доступен, начиная с версии 8.3.23.

Синтаксис:
ПоддерживаетсяСканированиеДокументов()
Возвращаемое значение:
Тип: Булево.
Возвращает значение Истина в следующих случаях:
на Android - при наличии камеры на устройстве,

на iOS - если система поддерживает видеозапись.
Возвращает значение Ложь на устройствах под управлением ОС семейства Windows.
Описание:

Определяет, поддерживается ли сканирование документов.

Доступность:

Мобильный клиент, мобильное приложение (клиент).

См. также:
СредстваМультимедиа, метод ПоказатьСканированиеДокументов
СредстваМультимедиа

Использование в версии:

Доступен, начиная с версии 8.3.23.

Методическая информация

Практические примеры

Сканирование документов: реальные страницы, порядок и пять оценок качества

Полный модуль своего автономного мобильного Пульта: сканирование документов: реальные страницы, порядок и пять оценок качества. Подготовка, действительные источники данных, отмена, границы контекста и контроль результата описаны отдельно.

Где и как запускать

Полный модуль управляемой формы Пульт собственного автономного мобильного приложения УчебноеМультимедиа85; здесь не выполнялся.

Подготовка

  1. Создать НОВУЮ отдельную конфигурацию УчебноеМультимедиа85 для автономного мобильного приложения8.5.1.1343; совместимость Не использовать. Не рабочую базу. Для опытов нужен свой Android/iOS и соответствующая мобильная платформа, не Windows desktop и не подключенный мобильный клиент.

  2. Конфигуратор → Обработки → УчебноеМультимедиа85 → Формы → Пульт: управляемая форма. Вставить ВЕСЬ модуль только одного урока. Его ПриОткрытии и ПередЗакрытием назначить событиям формы через конструктор. ПриОткрытии имеет Отказ; ПередЗакрытием — четыре аргумента Отказ, ЗавершениеРаботы, ТекстПредупреждения, СтандартнаяОбработка.

  3. Реквизиты формы: Согласие — Булево, начальное значение Ложь; Итог — Строка неограниченной длины, многострочное поле только просмотра. Для камеры/документов дополнительно Предпросмотр — Картинка и поле картинки с этим путем к данным.

  4. Создать команды СканироватьЧерезОповещения, СканироватьАсинх, действия с точно теми же именами и кнопки. При снятом Согласие новая операция не начинается; результат сканирования также не принимается без согласия.

  5. Для штрихкодового урока добавить РазрешенныйКод — Строка длины13 и поле ввода; до открытия сканера вписать цифры своей реальной упаковки. Для остальных уроков реквизит не нужен.

  6. Сохранить свою конфигурацию, проверить и обновить собственную базу (F7). Включить требуемую функциональность мобильного приложения — камеру/микрофон для выбранного урока — и развернуть только собственный учебный пакет на своем устройстве обычным для вашей мобильной платформы способом. Здесь сборка пакета, установка и F7 не выполнялись.

  7. На устройстве самостоятельно дать нужные разрешения ОС только перед своим опытом. Согласие на форме не заменяет разрешение ОС. Снимать только свою бумагу/упаковку, записывать свою короткую фразу; не чужие лица, разговоры, документы или экран.

  8. Весь модуль содержит проверенные ветви препроцессора: мобильные API только в МобильноеПриложениеКлиент, имя базы — только в МобильноеПриложениеСервер. Проверка базы локальная для автономного приложения, не сетевой сервер. API также существует у мобильного клиента, но этот конкретный стенд намеренно автономный.

  9. runtimeVerifiedScenarios=0. Проверена только установленная справка и исходный HTML/код. Камера, микрофон, голос, устройство, 1С и ОС-разрешения здесь не запускались; новых резервных копий не создано.

#Если МобильноеПриложениеКлиент Тогда
Перем СвойЗапуск, СвояОперация, СвояГотовность;
Перем СвоиСтраницы;

&НаКлиенте
Процедура ПриОткрытии(Отказ)
    СвойЗапуск = Неопределено;
    СвояОперация = "";
    СвояГотовность = Ложь;
    Согласие = Ложь;
    Итог = "Установите согласие только перед собственным опытом";
    Попытка
        ПроверитьСвойМобильныйСтендНаСервере();
        Если ТипЗнч(СредстваМультимедиа) <> Тип("СредстваМультимедиа") Тогда
            ВызватьИсключение "Нужен реальный глобальный мобильный объект мультимедиа";
        КонецЕсли;
        СвояГотовность = Истина;
    Исключение
        Отказ = Истина;
        ВызватьИсключение;
    КонецПопытки;
КонецПроцедуры

&НаКлиенте
Процедура ПередЗакрытием(Отказ, ЗавершениеРаботы, ТекстПредупреждения, СтандартнаяОбработка)
    СтандартнаяОбработка = Истина;
    Если СвояОперация <> "" Тогда
        Отказ = Истина;
        ТекстПредупреждения = "Сначала завершите только свой опыт: " + СвояОперация;
        Если Не ЗавершениеРаботы Тогда
            Сообщить(ТекстПредупреждения);
        КонецЕсли;
        Возврат;
    КонецЕсли;
    СвояГотовность = Ложь;
    СвойЗапуск = Неопределено;
КонецПроцедуры

&НаКлиенте
Процедура ПроверитьСвоеСогласие()
    Если Не СвояГотовность Или Не Согласие Тогда
        ВызватьИсключение "Нужны открытое собственное окно и явное согласие на этот опыт";
    КонецЕсли;
КонецПроцедуры

&НаКлиенте
Функция НачатьСвойОпыт(Операция)
    ПроверитьСвоеСогласие();
    Если СвояОперация <> "" Тогда
        ВызватьИсключение "Не запускайте второй собственный опыт до завершения первого";
    КонецЕсли;
    СвойЗапуск = Новый УникальныйИдентификатор;
    СвояОперация = Операция;
    Итог = Операция;
    Возврат СвойЗапуск;
КонецФункции

&НаКлиенте
Функция ЭтоСвойОпыт(Запуск)
    Возврат СвояГотовность И СвойЗапуск <> Неопределено И Запуск = СвойЗапуск;
КонецФункции

&НаКлиенте
Процедура ЗавершитьСвойОпыт(Запуск)
    Если ЭтоСвойОпыт(Запуск) Тогда
        СвойЗапуск = Неопределено;
        СвояОперация = "";
    КонецЕсли;
КонецПроцедуры

&НаКлиенте
Функция СоздатьСвоиПараметрыСканирования()
    Параметры = Новый ПараметрыСканированияДокументов;
    Параметры.БелыйФонДокумента = Истина;
    Параметры.ПрямоугольныйДокумент = Истина;
    Параметры.СканированиеСериями = Истина;
    Параметры.ПроверкаКачества = ПроверкаКачестваСканированияДокументов.ПредупреждатьНижеВысокого;
    Возврат Параметры;
КонецФункции

&НаКлиенте
Процедура СканироватьЧерезОповещения(Команда)
    Запуск = НачатьСвойОпыт("Сканирование с оповещениями");
    Предпросмотр = Неопределено;
    СвоиСтраницы = Новый Соответствие;
    Попытка
        Если Не СредстваМультимедиа.ПоддерживаетсяСканированиеДокументов() Тогда
            ВызватьИсключение "Сканирование документов этим устройством не поддерживается";
        КонецЕсли;
        Страница = Новый ОписаниеОповещения("СвояСтраницаПолучена", ЭтаФорма, Запуск);
        Завершение = Новый ОписаниеОповещения("СвояСерияЗавершена", ЭтаФорма, Запуск);
        СредстваМультимедиа.ПоказатьСканированиеДокументов("Два собственных учебных листа", Страница, Завершение, СоздатьСвоиПараметрыСканирования());
    Исключение
        СвоиСтраницы = Неопределено;
        ЗавершитьСвойОпыт(Запуск);
        ВызватьИсключение;
    КонецПопытки;
КонецПроцедуры

&НаКлиенте
Процедура СвояСтраницаПолучена(Результат, ДополнительныеПараметры) Экспорт
    Если Не ЭтоСвойОпыт(ДополнительныеПараметры) Тогда
        Возврат;
    КонецЕсли;
    Если Не Согласие Тогда
        СредстваМультимедиа.ЗакрытьСканированиеДокументов();
        Возврат;
    КонецЕсли;
    Если ТипЗнч(Результат) <> Тип("СтраницаСканированияДокументов") Тогда
        ВызватьИсключение "Нужна настоящая страница текущего сканирования";
    КонецЕсли;
    Идентификатор = Результат.Идентификатор;
    Если ТипЗнч(Идентификатор) <> Тип("Число") Тогда
        ВызватьИсключение "ID настоящей страницы должен быть числом, не номером строки своей таблицы";
    КонецЕсли;
    СвоиСтраницы.Вставить(Идентификатор, Результат);
    Если СвоиСтраницы.Количество() > 2 Тогда
        Итог = "В опыте принимаются не более двух разных полученных ID страниц; свое сканирование закрывается";
        СредстваМультимедиа.ЗакрытьСканированиеДокументов();
        Возврат;
    КонецЕсли;
    Если Не ПроверитьСвоюСтраницу(Результат) Тогда
        Итог = Итог + "; не считается годной страницей пакета";
    КонецЕсли;
КонецПроцедуры

&НаКлиенте
Процедура СвояСерияЗавершена(ИдентификаторыСтраниц, ДополнительныеПараметры) Экспорт
    Если Не ЭтоСвойОпыт(ДополнительныеПараметры) Тогда
        Возврат;
    КонецЕсли;
    ЗавершитьСвойОпыт(ДополнительныеПараметры);
    Если ИдентификаторыСтраниц = Неопределено Или Не Согласие Тогда
        СвоиСтраницы = Неопределено;
        Предпросмотр = Неопределено;
        Итог = "Серия отменена или согласие снято: пакет не принят";
        Возврат;
    КонецЕсли;
    Если ТипЗнч(ИдентификаторыСтраниц) <> Тип("Массив") Тогда
        ВызватьИсключение "Завершение возвращает массив реальных ID, не массив картинок";
    КонецЕсли;
    Страницы = Новый Массив;
    Для Каждого Идентификатор Из ИдентификаторыСтраниц Цикл
        Страница = СвоиСтраницы.Получить(Идентификатор);
        Если Страница = Неопределено Тогда
            ВызватьИсключение "Для итогового ID нет реально полученной страницы; неизвестные данные не придумываются";
        КонецЕсли;
        Страницы.Добавить(Страница);
    КонецЦикла;
    СвоиСтраницы = Неопределено;
    РазобратьСвойПакет(Страницы);
КонецПроцедуры

&НаКлиенте
Асинх Процедура СканироватьАсинх(Команда)
    Запуск = НачатьСвойОпыт("Сканирование с Ждать");
    Предпросмотр = Неопределено;
    Попытка
        Если Не СредстваМультимедиа.ПоддерживаетсяСканированиеДокументов() Тогда
            ВызватьИсключение "Сканирование документов этим устройством не поддерживается";
        КонецЕсли;
        Страницы = Ждать СредстваМультимедиа.СканироватьДокументыАсинх("Два собственных учебных листа", СоздатьСвоиПараметрыСканирования());
        Если Не ЭтоСвойОпыт(Запуск) Тогда
            Возврат;
        КонецЕсли;
        ЗавершитьСвойОпыт(Запуск);
        Если Страницы = Неопределено Или Не Согласие Тогда
            Итог = "Серия отменена или согласие снято: пакет не принят";
            Возврат;
        КонецЕсли;
        РазобратьСвойПакет(Страницы);
    Исключение
        ЗавершитьСвойОпыт(Запуск);
        ВызватьИсключение;
    КонецПопытки;
КонецПроцедуры

&НаКлиенте
Функция ПроверитьСвоюСтраницу(Страница)
    Если ТипЗнч(Страница) <> Тип("СтраницаСканированияДокументов") Тогда
        ВызватьИсключение "Проверяется только настоящая страница своего результата";
    КонецЕсли;
    Изображение = Страница.ДанныеИзображения;
    Двоичные = ПолучитьСвоиНебольшиеДанные(Изображение, "image/");
    Предпросмотр = Новый Картинка(Двоичные);
    Если Не Страница.ДокументНайден Тогда
        Итог = "ID " + Строка(Страница.Идентификатор) + ": граница документа не найдена; исходное фото показано, страница не принята";
        Возврат Ложь;
    КонецЕсли;
    Качество = Страница.ПараметрыКачества;
    Если ТипЗнч(Качество) <> Тип("ПараметрыКачестваСканированияДокументов") Тогда
        ВызватьИсключение "Нужны реальные оценки качества полученной страницы";
    КонецЕсли;
    Оценки = Новый Структура("Белый,Граница,Текст,Общее,Перспектива", Качество.КачествоБелого,
        Качество.КачествоГраницы, Качество.КонтрастностьТекста, Качество.ОбобщенноеКачество, Качество.ПерспективныеИскажения);
    Принята = Истина;
    ОтчетОценок = "";
    Для Каждого Оценка Из Оценки Цикл
        Если ТипЗнч(Оценка.Значение) <> Тип("Число") Или Оценка.Значение < 1 Или Оценка.Значение > 10 Тогда
            ВызватьИсключение "Реальная нормированная оценка должна быть в диапазоне1..10";
        КонецЕсли;
        Если Оценка.Значение < 7 Тогда
            Принята = Ложь;
        КонецЕсли;
        ОтчетОценок = ОтчетОценок + Оценка.Ключ + "=" + Строка(Оценка.Значение) + "; ";
    КонецЦикла;
    Итог = "ID " + Строка(Страница.Идентификатор) + ": " + ОтчетОценок + ?(Принята, "принята по собственной политике", "нужно переснять по собственной политике");
    Сообщить(Итог);
    Возврат Принята;
КонецФункции

&НаКлиенте
Процедура РазобратьСвойПакет(Страницы)
    Если ТипЗнч(Страницы) <> Тип("Массив") Или Страницы.Количество() = 0 Или Страницы.Количество() > 2 Тогда
        ВызватьИсключение "Собственный учебный пакет содержит одну или две реальные страницы";
    КонецЕсли;
    ID = Новый Соответствие;
    ВсеПриняты = Истина;
    Порядок = "";
    Для Каждого Страница Из Страницы Цикл
        Если ТипЗнч(Страница) <> Тип("СтраницаСканированияДокументов") Тогда
            ВызватьИсключение "Пакет должен содержать настоящие страницы, не номера или свои пустые объекты";
        КонецЕсли;
        Идентификатор = Страница.Идентификатор;
        Если ТипЗнч(Идентификатор) <> Тип("Число") Или ID.Получить(Идентификатор) <> Неопределено Тогда
            ВызватьИсключение "Итоговые ID должны быть действительными и не повторяться";
        КонецЕсли;
        ID.Вставить(Идентификатор, Истина);
        Если Не ПроверитьСвоюСтраницу(Страница) Тогда
            ВсеПриняты = Ложь;
        КонецЕсли;
        Порядок = Порядок + Строка(Идентификатор) + "; ";
    КонецЦикла;
    Итог = "Порядок реальных ID: " + Порядок + ?(ВсеПриняты, "Весь собственный пакет принят", "Пакет не принят: есть страница для пересъемки");
КонецПроцедуры

&НаКлиенте
Функция ПолучитьСвоиНебольшиеДанные(Данные, СемействоMIME)
    Если ТипЗнч(Данные) <> Тип("ДанныеМультимедиа") Тогда
        ВызватьИсключение "Нужен настоящий результат своего мобильного захвата";
    КонецЕсли;
    Если Лев(Данные.ТипСодержимого, СтрДлина(СемействоMIME)) <> СемействоMIME Тогда
        ВызватьИсключение "Получен другой вид мультимедиа, не " + СемействоMIME;
    КонецЕсли;
    Двоичные = Данные.ПолучитьДвоичныеДанные();
    Если Двоичные.Размер() = 0 Или Двоичные.Размер() > 33554432 Тогда
        ВызватьИсключение "Для этого собственного опыта нужен непустой результат не более32МиБ";
    КонецЕсли;
    Возврат Двоичные;
КонецФункции
#Иначе
&НаКлиенте
Процедура ПриОткрытии(Отказ)
    Отказ = Истина;
    Сообщить("Откройте свою отдельную автономную мобильную базу УчебноеМультимедиа85, не desktop или подключенный мобильный клиент");
КонецПроцедуры

&НаКлиенте
Процедура ПередЗакрытием(Отказ, ЗавершениеРаботы, ТекстПредупреждения, СтандартнаяОбработка)
    Отказ = Ложь;
    СтандартнаяОбработка = Истина;
КонецПроцедуры

&НаКлиенте
Процедура СканироватьЧерезОповещения(Команда)
    ВызватьИсключение "Этот собственный урок только для автономного мобильного приложения";
КонецПроцедуры

&НаКлиенте
Процедура СканироватьАсинх(Команда)
    ВызватьИсключение "Этот собственный урок только для автономного мобильного приложения";
КонецПроцедуры
#КонецЕсли

&НаСервереБезКонтекста
Процедура ПроверитьСвойМобильныйСтендНаСервере()
#Если МобильноеПриложениеСервер Тогда
    Если ТранзакцияАктивна() Тогда
        ВызватьИсключение "Собственный опыт не запускается внутри чужой транзакции";
    КонецЕсли;
#Иначе
    ВызватьИсключение "Этот стенд требует локального сервера автономного мобильного приложения";
#КонецЕсли
КонецПроцедуры

Разбор по шагам

  1. Подготовить один-два собственных белых прямоугольных листа с крупными надписями Учебная страница1 и2. Это не OCR: содержание ученик сверяет глазами по Предпросмотр.

  2. Создать свои параметры: белый фон и прямоугольный документ включены, серии включены, native предупреждает ниже высокого качества. Открывать сканер только после проверки поддержки устройства и согласия.

  3. В callback страницы приходит реальная СтраницаСканированияДокументов. Ее ID хранится ключом соответствия, сам объект — значением; повторный приход того же ID заменяет только последнюю полученную версию.

  4. Callback завершения возвращает массив ID в порядке пользователя, не страницы. Собирать пакет строго по этому массиву; страницы, удаленные пользователем из итоговой серии, не переносятся из всего кэша по порядку обхода соответствия.

  5. Этот собственный callback-опыт ограничен двумя различными полученными ID. Третий закрывает именно свой интерфейс через ЗакрытьСканированиеДокументов. Это лимит своего кэша, не количество текущих видимых страниц после пользовательского удаления.

  6. Асинх-вариант использует Ждать: готовый результат уже является упорядоченным массивом реальных страниц. Не обращаться к Обещание как к массиву до завершения и не смешивать результаты двух вариантов.

  7. ДанныеИзображения проверить и преобразовать в реальную Картинка. Если ДокументНайден=Ложь, показывается исходное фото, но страница не принимается как обнаруженный документ.

  8. Для найденного документа прочитать реальные КачествоБелого, КачествоГраницы, КонтрастностьТекста, ОбобщенноеКачество и ПерспективныеИскажения. Диапазон каждой оценки1..10. Собственная строгая политика принимает только все пять>=7; это отдельное решение приложения, не замена native-алгоритма ОбобщенноеКачество.

  9. Проверить отмену, порядок2→1, низкое качество одного листа и третий distinct-ID. ID не перенумеровываются и readonly-свойства не присваиваются; весь пакет принимается только при годности каждой его страницы.

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

  1. Будущий ручной запуск должен получить настоящий результат выбранного API на своем устройстве и пройти условия своего урока. Положительный флаг поддержки или отсутствие исключения само по себе не означает, что данные получены.

  2. Без согласия новая операция должна отказать. Отмена должна оставлять отмену, а ошибка запуска — ошибку; второе нажатие не должно подменять активный GUID собственного опыта.

  3. Проверьте отдельный отрицательный опыт по шагам урока: отсутствие голосового пакета, отмену захвата, чужой код или низкое качество/лишнюю страницу. Не подставляйте фиктивный объект или ожидаемые байты вместо результата платформы.

  4. После освобождения собственного сеанса форму можно закрыть. При собственном активном сеансе ПередЗакрытием должен предложить сначала завершить его; поздний callback другого GUID не должен изменить Итог.

  5. runtimeVerifiedScenarios=0. Все аппаратные результаты, ошибки и проверки здесь — условия будущей ручной приемки, а не выполненный тест1С.

Ожидаемый результат

Подготовлен самостоятельный мобильный урок с собственным сеансом и действительными результатами платформы; аппаратно здесь не запускался.

На что обратить внимание

  1. СредстваМультимедиа — глобальное readonly-свойство мобильного контекста. Не создавать этот объект через Новый, не передавать неизвестный ИсходныйОбъект и не переносить вызовы в серверный/desktop-код.

  2. Этот полный стенд рассчитан на автономное мобильное приложение. Серверная проверка имени конфигурации работает локально на устройстве; Метаданные.Имя не читается в мобильной клиентской ветви.

  3. Поддерживается... — проверка возможностей, не разрешений ОС, занятости камеры/микрофона, качества изображения или слышимости звука. Отказ ОС и отмена пользователя требуют отдельной проверки.

  4. Имена публичных callback связаны с настоящими ОписаниеОповещения и проверяются по GUID. Для аудио, текста, страницы, завершения серии и штрихкода сигнатуры различны; их нельзя заменять одним универсальным обработчиком.

  5. Код явно не сохраняет медиа, не вызывает HTTP, почту, печать или бизнес-запись. Платформа/ОС могут использовать свой временный кэш; очистка переменной не доказывает удаление этого кэша. Размер32МиБ проверяется после получения байтов и не обещает предотвратить их первоначальную аллокацию.

  6. Нормированная оценка сканирования не является OCR, распознанным текстом или гарантией юридической пригодности документа. Строгая политика>=7 каждого показателя — решение этого собственного примера.

  7. Callback остановки звука/текста не всегда означает окончательное завершение: уведомление может временно прервать звук с последующим возобновлением. В этих уроках владелец сеанса снимается явной собственной командой остановки, не предположением о причине callback.

  8. ПередЗакрытием имеет четыре аргумента. При ЗавершениеРаботы=Истина нельзя открывать окна или вызывать сервер: заполняется ТекстПредупреждения. Пользователь или ОС могут принудительно завершить приложение; отказ от обычного закрытия не гарантирует запрет этого. Всегда явно остановите свой микрофон/звук до выхода.

Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.

Не хотите разбираться сами?

Адаптируем это решение под вашу базу. Оценка бесплатно.

Оставить задачу

1С, 1С:Предприятие — товарные знаки ООО «1С». Сайт не является официальным представительством фирмы «1С» и не аффилирован с ней.