ABBYY Mobile Capture

ABBYY Mobile Capture позволяет встроить в мобильный сценарий автоматическую съёмку документов, распознавание текста прямо в кадре, извлечение заданных полей и подготовку выровненных страниц для PDF или серверной обработки. Камера сама ищет границы листа, подсказывает приблизить телефон или удерживать его неподвижно, исправляет перспективу, а разработчик задаёт число страниц, разрешение, формат экспорта и правила проверки результата.

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

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

Скачать ABBYY Mobile Capture

Оценка 9.7 Рекомендуем
  • Редактирование PDF
  • Русский интерфейс
  • Просто новичкам
Скачать бесплатно на Windows
Лучшая альтернатива
ABBYY Mobile Capture
Оценка 8.5
  • Нужна интеграция
  • Требуется лицензия
  • Только iOS и Android
Скачать ABBYY Mobile Capture
Загрузка начнётся после нажатия

Как устроен сценарий съёмки документа

Сценарий начинается не с обычной кнопки системной камеры, а с контролируемого видеопотока. Алгоритм непрерывно оценивает кадры, выделяет четырёхугольник листа и ждёт момента, когда документ достаточно крупный, резкий и устойчивый. Такой порядок нужен не ради декоративной анимации: для OCR критично, чтобы мелкие штрихи не размазались, углы не вышли за границы кадра, а блик не закрыл строку. Поэтому подсказки Looking for document, Closer и Keep still следует воспринимать как часть контроля качества, а не как необязательные сообщения.

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

Интерфейс ABBYY Mobile Capture

Кнопка галереи подключает уже сохранённую фотографию к тому же процессу. Это помогает, когда документ прислали в мессенджере или сняли заранее, но импортированный файл нельзя считать автоматически качественным. Для него всё равно проверяют размер, ориентацию, границы и пригодность для распознавания; слишком большой снимок разумно уменьшить до установленного предела, иначе растут память и время обработки без заметной прибавки точности.

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

Захваченный кадр возвращается приложению только после завершения выбранного сценария. При точном количестве страниц кнопка сохранения становится доступной, когда набрано заданное число. При неограниченном режиме пользователь сам решает, когда перейти к редактору, поэтому важно явно показывать счётчик и понятную кнопку завершения, иначе многостраничная съёмка выглядит как бесконечный цикл камеры.

Подсказки, рамка и логика автоматического спуска

Рамка документа должна обновляться без заметного отставания от движения телефона. Если она прыгает между краем бумаги и рисунком внутри бланка, полезно задать ожидаемое соотношение сторон. Для листа A4, визитной карточки или Letter известная геометрия отсекает ложные четырёхугольники; для чеков, посылочных ярлыков и произвольных заявлений оставляют режим Any либо задают собственные размеры в миллиметрах.

Параметр minimumDocumentToViewRatio определяет, какую долю видимой области должен занимать лист. Значение по умолчанию 0,15 допускает сравнительно далёкий документ. Повышение порога заставляет пользователя приблизиться и обычно даёт больше пикселей на символ, но слишком жёсткое значение мешает снять крупный лист на небольшом столе. Настройку проверяют на самых компактных поддерживаемых телефонах, а не только на современном устройстве с широкоугольной камерой.

Ограничения aspectRatioMin и aspectRatioMax работают парой и задают интервал допустимой формы. Узкий интервал повышает устойчивость на однотипных бланках, но начинает отвергать реальные документы, если пользователь загнул угол или снимает лист под сильным наклоном. Для общего сканера лучше широкий диапазон и ручная коррекция, для банковской формы фиксированного образца — более строгая геометрия.

Подсказку Closer показывают, когда документ найден, но занимает недостаточно места. Keep still появляется, когда геометрия уже приемлема, а движению нужно затихнуть на несколько кадров. Эти сообщения стоит локализовать коротко: длинная строка перекрывает документ и плохо читается на фоне видеопотока. Хорошие русские варианты — Приблизьте документ и Не двигайте телефон; инструкция о бликах и тенях лучше размещается отдельной строкой до открытия камеры.

Автоспуск не избавляет от кнопки отмены. Выход должен быть предсказуемым: при пустой сессии закрытие возвращает предыдущий экран, при уже снятых страницах появляется предупреждение о потере. Текст предупреждения необходимо заменить на пользовательский, а не оставлять технические ключи локализации. Реальный пример с необработанными строками DectructiveActionWarning показывает, что отсутствие одного ресурсного файла сразу превращает аккуратный экран в непонятный диалог.

Экран настроек в демонстрационном приложении

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

Orientation принимает Portrait, Landscape или Default. Автоматический вариант подходит для общего сценария, но в киоске с закреплённым планшетом лучше выбрать конкретное положение, чтобы интерфейс не поворачивался при каждом движении. При фиксированной ориентации необходимо проверить, совпадает ли она с разрешёнными ориентациями самого приложения, иначе камера и кнопки могут оказаться повернуты по-разному.

Интерфейс ABBYY Mobile Capture

Show preview enabled меняет переход после каждого кадра. Когда предварительный просмотр отключён, камера сразу продолжает съёмку, что ускоряет пачку документов. Когда включён, пользователь видит страницу и может заметить обрезанный угол до завершения сессии. Для редких, но ценных документов — паспорта, подписанного договора, оригинала доверенности — дополнительный контроль обычно важнее скорости.

Required page count равен нулю для неограниченной серии или положительному числу для точного комплекта. Точное значение удобно для разворота удостоверения, где всегда нужны две стороны, либо для заявления из трёх листов. Нельзя бездумно задавать число для документов переменного состава: пользователь не сможет завершить работу после двух реальных страниц, если интерфейс ждёт третью.

Destination File сохраняет результат во временный или заданный путь и возвращает URI. Destination Base64 передаёт строку в память JavaScript, но в готовом сценарии допускается только для одной страницы. Для нескольких кадров Base64 резко увеличивает объём данных и создаёт лишнее копирование, поэтому библиотека требует файловый результат.

Настройки изображения и геометрии

Блок Default Image Settings задаёт геометрию ещё до открытия камеры. Document size выбирают из A4, BusinessCard, Letter, Any либо записывают как ширину и высоту в миллиметрах. Физический размер нужен не для печати, а для правильного выравнивания и вычисления пропорций; если указать визитку для листа A4, алгоритм будет искать слишком вытянутую рамку и чаще предлагать ручную съёмку.

Gallery image max size ограничивает максимальную сторону импортированного изображения; в примере используется 4096 пикселей. Это разумный компромисс для большинства текстовых документов: разрешения хватает для мелкого шрифта, а декодирование не занимает сотни мегабайт. Уменьшение до 1600–2000 пикселей ускорит обработку, но может повредить распознаванию таблиц, номеров и тонких символов.

Интерфейс ABBYY Mobile Capture

Min document to view ratio имеет смысл тестировать вместе с фокусным расстоянием. Телефоны с автоматическим переключением объективов иногда меняют масштаб при приближении, и документ внезапно становится меньше в кадре. Если производственное приложение блокирует конкретную камеру, порог можно настроить точнее; при большом парке устройств лучше оставить запас и контролировать качество отдельной оценкой после съёмки.

Интервал aspect ratio особенно эффективен на банковских картах, визитках и удостоверениях. Для сложенного пополам документа или чека переменной длины фиксировать его опасно. Практическое правило: ограничивать форму только тогда, когда бизнес-процесс однозначно знает тип входного документа до открытия камеры.

Настройки разрешения HD, FullHD и UHD_4K влияют одновременно на скорость, нагрев, объём файла и шанс прочитать мелкий текст. FullHD установлен как базовый вариант. 4K оправдан для маленьких реквизитов и архивных бланков, но на слабом устройстве может снизить частоту кадров и усложнить автоспуск. HD используют в сценариях, где важна скорость и распознаются крупные поля, например номер контейнера или короткий код.

Выбор значений и защита от неверной конфигурации

В демонстрационном приложении значения с ограниченным набором открываются через action sheet. Для ориентации это Default, Portrait и Landscape; аналогично выбираются разрешение, формат, место возврата и сжатие. Такой элемент лучше свободного текстового поля, потому что исключает опечатку и сразу показывает допустимые варианты.

Числовые параметры требуют отдельной проверки. Нулевое число страниц имеет специальный смысл, отрицательное не должно доходить до библиотеки. Доля документа ограничивается диапазоном от нуля до единицы. Минимальное соотношение сторон не может превышать максимальное, а строка размера должна содержать два положительных целых числа, разделённых символом x.

Интерфейс ABBYY Mobile Capture

Настройки полезно собирать в один объект перед стартом и журналировать без персональных данных. Тогда ошибка воспроизводится по фактическому набору параметров, а не по предположениям тестировщика. Лицензионный файл, пути к кадрам и содержимое Base64 в журнал не помещают; достаточно имени сценария, ОС, разрешения, формата, числа страниц и кода завершения.

При обновлении переключателя демонстрационный код сразу записывает значение в общий объект. В промышленной форме безопаснее иметь кнопки Применить и Сбросить, иначе случайное касание меняет следующий запуск камеры. Особенно это относится к отключению кнопки галереи или ручного спуска: пользователь может не понять, почему привычный элемент исчез.

Предустановки сокращают число комбинаций. Например, Паспорт задаёт две страницы, FullHD, предварительный просмотр и фиксированную ориентацию; Пакет накладных — неограниченное число, быстрый переход без просмотра и PDF; Реквизиты счёта — одна страница, OCR, языки документа и профиль IBAN.

Редактор страниц после съёмки

После первого кадра пользователь может продолжить съёмку или открыть редактор. В редакторе важны не художественные инструменты, а контроль комплекта: Add page добавляет лист, Continue начинает следующий документ, Save завершает, индекс вида 2 из 5 показывает положение. Кнопки удаления должны различать одну страницу и всю сессию, иначе одно неверное подтверждение уничтожит пачку.

Ручной Crop показывает четыре угла документа. Перетаскивать нужно именно вершины, а не обрезать прямоугольник по горизонтали: после подтверждения выполняется перспективное преобразование, поэтому трапециевидный лист становится прямоугольным. Autocrop повторяет автоматическое определение, Original возвращает исходный кадр, Accept применяет контур, Cancel отменяет изменение.

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

Удаление страницы не должно сразу менять серверный документ. Сначала редактируется локальный набор, затем после Save формируется окончательный массив файлов или PDF. Если передача выполняется сразу после каждого кадра, необходимо вести идентификаторы и отправлять операцию удаления; иначе на сервере останется страница, которую пользователь убрал из интерфейса.

Для многостраничного документа полезна проверка порядка. Базовый редактор показывает последовательность и позволяет добавлять страницы; если бизнес-процесс требует произвольной перестановки, её реализуют на стороне приложения либо до экспорта. Нельзя предполагать наличие сложного PDF-органайзера с разделением, объединением и закладками: задача этого интерфейса — получить корректный набор изображений.

Формирование результата и экран проверки

При экспорте в JPG или PNG возвращается массив images. Для каждого элемента доступны путь либо Base64 и сведения о размере, а общий resultInfo содержит префикс URI. Приложение должно обрабатывать массив даже при одной странице: это упрощает единый код для одиночного и многостраничного сценария.

Демонстрационный экран выводит кадры горизонтальной лентой и ниже показывает сокращённое JSON-представление результата. В пользовательском приложении технический JSON не нужен, но разработчику он помогает проверить фактический формат, пути и размеры. На этапе интеграции полезно временно сохранить такой диагностический блок за скрытым режимом, а перед выпуском убрать его из обычного интерфейса.

Интерфейс ABBYY Mobile Capture

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

Base64 стоит применять только когда внешний API принимает строку и документ гарантированно мал. JPEG размером 4 МБ превращается примерно в 5,3 МБ текста, затем копируется между нативным слоем и JavaScript. На нескольких страницах это создаёт пиковое потребление памяти и задержку интерфейса, поэтому файловый URI почти всегда практичнее.

Ошибку нельзя смешивать с успешным объектом. Демонстрационный код помещает текст исключения в то же поле результата для наглядности, но рабочее приложение должно иметь отдельные состояния: отменено пользователем, отказано в разрешении, не найдена лицензия, камера недоступна, недостаточно памяти, экспорт не выполнен. Тогда оператор увидит понятное действие, а аналитика — точную причину.

Экспорт страниц в PDF

Режим Pdf объединяет все захваченные изображения в один файл. Для отдельного вызова exportImagesToPdf передаётся список изображений, степень сжатия и при необходимости размер каждой страницы. В метаданных можно задать название и автора; результатом становится URI готового документа.

Такой PDF состоит из изображений страниц. Наличие выполненного OCR отдельно не означает, что текст автоматически встроен в скрытый слой PDF. Если бизнес-процесс требует поиск, выделение и копирование текста внутри файла, приложение должно создать соответствующий текстовый слой другим компонентом или выбрать решение, которое прямо заявляет формирование searchable PDF.

Интерфейс ABBYY Mobile Capture

Размер PDF зависит от разрешения и сжатия каждого кадра. Для цветной накладной с печатями высокая степень JPEG-сжатия может размыть мелкие цифры, а PNG сохранит детали, но даст тяжёлый файл. Практический профиль определяют измерением: сравнивают читаемость и точность OCR на реальных документах, затем устанавливают верхний предел размера для отправки.

Перед открытием PDF нужно убедиться, что запись завершилась и файл не пуст. На iOS путь иногда преобразуется в имя временного файла для просмотрщика; на Android обычно используется полный URI. Нельзя хранить платформенную логику в бизнес-коде каждого экрана — лучше один адаптер, который нормализует путь и предоставляет метод открытия.

Просмотрщик в демонстрационном приложении помещён в модальное окно с кнопкой Close. В реальном процессе к нему добавляют номер страницы, повторную съёмку и подтверждение отправки. Редактирование текста, перестановка объектов, подпись и защита паролем не относятся к базовому экспортному вызову; такие операции выполняются отдельным PDF-компонентом.

Распознавание текста на фотографии

Метод recognizeText принимает URI изображения, имя лицензии, языки распознавания и флаг определения ориентации. Возвращается полный текст, угол поворота, предупреждения и структура блоков. Внутри блока есть строки, прямоугольники и четырёхугольники, а для символов — геометрия и признаки начертания либо неуверенности.

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

Языки задают до распознавания. Слишком широкий набор увеличивает конкуренцию похожих алфавитов и может ухудшить результат на коротких полях. Для российского паспорта разумно включить русский и английский, для латинского IBAN — нужные латинские языки, а для одноязычной формы не подключать десятки ресурсов на всякий случай.

Определение ориентации полезно для снимка из галереи, но не заменяет нормальную съёмку. Перевёрнутая страница распознаётся после поворота, однако сильная перспектива, смаз и блик остаются. Лучший порядок — определить границы, выровнять и повернуть изображение, оценить качество, затем запускать OCR.

Предупреждения ProbablyLowQualityImage и ProbablyWrongLanguage нужно превращать в действие. При низком качестве предложить переснять или принять на ответственность пользователя; при вероятно неверном языке — повторить с другим набором. Скрытое игнорирование предупреждений даёт формально успешный ответ с большим числом ошибок.

Извлечение структурированных данных

Метод extractData нужен, когда приложению важен не весь текст, а поля. Профиль задаёт тип документа либо правила поиска, а результат содержит dataFields с идентификатором, именем, текстом, координатами и вложенными компонентами. Это позволяет сразу заполнить форму, но каждое критичное значение всё равно должно иметь экран подтверждения.

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

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

Регулярное выражение не исправляет ошибку распознавания. Если цифра 0 прочитана как O, строгий шаблон не найдёт поле. Для номеров с известной структурой можно нормализовать символы только в позициях, где разрешены цифры, но исправление должно быть прозрачным и подтверждаемым, особенно для банковских реквизитов.

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

Захват текста непосредственно из видеопотока

Режим real-time OCR распознаёт текст в последовательности кадров, не требуя отдельной фотографии. Он полезен для короткого номера, адреса или кода, который нужно сразу перенести в форму. Результаты нескольких кадров можно объединять: стабильная строка считается более надёжной, чем единичное чтение на смазанном кадре.

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

Для постоянной частоты интерфейса нельзя обрабатывать каждый кадр тяжелее, чем камера его выдаёт. Новую задачу запускают после завершения предыдущей либо отбрасывают промежуточные кадры. Очередь из десятков кадров создаёт задержку: пользователь уже убрал документ, а приложение продолжает показывать старые результаты.

Условия остановки задаются бизнес-логикой. Можно завершить после нескольких одинаковых результатов, после прохождения контрольной суммы или по нажатию пользователя. Немедленное принятие первого совпадения опасно для похожих символов, а ожидание абсолютной стабильности раздражает на слабых устройствах.

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

Границы, перспективное исправление и поворот

Core API позволяет отделить обработку от готового интерфейса. detectDocumentBoundary возвращает четыре точки контура, cropImage выравнивает и обрезает изображение, rotateImage поворачивает на заданный угол. Эти методы полезны, когда компания строит собственную камеру или обрабатывает файлы из другого источника.

Порядок точек нельзя менять случайно. Контур передают в ожидаемой последовательности вокруг документа; перекрёстный порядок даст самопересекающийся четырёхугольник и искажённый результат. Перед обрезкой проверяют, что точки находятся внутри изображения, площадь не близка к нулю и стороны не пересекаются.

Автоматический контур следует сохранять вместе с исходником до подтверждения. Если пользователь позже замечает обрезанную печать, можно вернуть исходный кадр и поправить углы, не требуя повторной съёмки. После окончательного принятия исходник удаляют или архивируют согласно политике хранения.

Поворот на 90, 180 или 270 градусов применяют до OCR. Если просто повернуть отображение виджета, пиксели для движка останутся прежними, а координаты текста не совпадут с экраном. Удобнее нормализовать файл и далее использовать единую систему координат.

Перспективное исправление растягивает дальний край и может усилить шум. Поэтому документ всё равно следует снимать как можно ближе к перпендикуляру. Алгоритм исправляет разумный наклон, но не превращает узкую диагональную полоску в качественный скан.

Оценка качества для OCR

assessQualityForOcr возвращает блоки оценки для областей изображения. Вместо общего ответа хорошо/плохо приложение видит тип области, показатель качества и прямоугольник. Можно подсветить проблемный участок, например мелкий текст в тени, и попросить переснять только когда он действительно важен.

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

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

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

Порог качества выбирают по стоимости ошибки. Для внутренней заметки можно принять средний кадр, для автоматического платежа — потребовать пересъёмку или ручное подтверждение. Один универсальный порог на все документы редко работает: мелкая выписка и крупный номер накладной предъявляют разные требования.

Локализация встроенного интерфейса

На Android тексты и видимость элементов CaptureView настраиваются через XML и строковые ресурсы. Ссылки вида @string удобны тем, что Android сам выбирает язык. Не следует записывать русский текст прямо в layout: это усложнит перевод и приведёт к смеси языков при смене локали.

На iOS строки разделены по экранам. AbbyyUI.strings относится к камере, AbbyyUI.stringsdict хранит формы множественного числа для счётчика, AbbyyPagesEditor.strings управляет редактором и просмотром, AbbyyCrop.strings — ручной обрезкой. Файл создаётся для каждого языка, после чего контроллеру указывают bundle с заменами.

Список редактора включает Add page, Continue, Save, номера текущего документа, подтверждения удаления и сообщения об ошибке. Экран обрезки содержит Cancel, Accept, Autocrop, Original и заголовок Crop. Камера использует Looking for document, Closer, Keep still, сообщения о доступе к камере и галерее и текст неподдерживаемого устройства.

Проверять нужно не только перевод, но и длину. Русская строка часто длиннее английской и может не поместиться на кнопке. В камере лучше короткие глаголы Снять, Готово, Добавить, а подробное объяснение вынести в подсказку или диалог.

Особое внимание требуется plural-формам: 1 страница, 2 страницы, 5 страниц. Простая подстановка английской строки с числом выглядит непрофессионально. На iOS правильные варианты задаются stringsdict, на Android — plurals.

Разрешения камеры и галереи

Без разрешения камеры сценарий не стартует. На iOS в Info.plist добавляют NSCameraUsageDescription и, если разрешён импорт, NSPhotoLibraryUsageDescription. Текст объясняет конкретную пользу: Камера нужна для съёмки документов, а не абстрактное для работы приложения.

На Android разрешение запрашивают непосредственно перед первым открытием камеры. Если пользователь отказал один раз, можно показать объяснение и повторить; при постоянном запрете — кнопку перехода в системные настройки. Бесконечно вызывать системный диалог нельзя: после жёсткого отказа он больше не появится.

Кнопку галереи скрывают, если сценарий запрещает импорт. Это лучше, чем показывать элемент и после нажатия сообщать об ограничении. Если галерея разрешена, приложение должно корректно читать URI провайдера, а не предполагать обычный путь к файлу.

При возвращении из настроек разрешение проверяют заново. Экран камеры мог остаться в памяти, но ресурс ещё не открыт. Надёжная реализация пересоздаёт сессию и показывает загрузку, чтобы пользователь не видел чёрный предпросмотр.

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

Подключение к Android-проекту

В Android-проект добавляются AAR-библиотеки ABBYY и UI-компонент, а каталог assets подключается как источник ресурсов. Лицензионный файл помещается в assets под ожидаемым именем MobileCapture.License либо это имя передаётся в настройках. Если файл лежит в другом модуле или переименован системой сборки, инициализация завершится ошибкой.

Минимальный уровень Android — API 21. В ndk.abiFilters перечисляются armeabi-v7a, arm64-v8a, x86 и x86_64 в зависимости от целевых устройств. Если оставить только ARM, приложение не запустится на x86-эмуляторе; если включить все архитектуры без необходимости, пакет заметно вырастет.

При конфликте libc++_shared.so используются packagingOptions pickFirst для каждой архитектуры. Это не универсальное решение любого нативного конфликта: выбранные библиотеки должны быть совместимы. После изменения зависимостей тестируют запуск и основные операции на каждой ABI, а не ограничиваются успешной сборкой.

FlatDir указывает Gradle, где искать локальные AAR. Старый пример с внедрением зависимостей в afterEvaluate может потребовать адаптации к современным версиям Android Gradle Plugin. Ошибку Failed to resolve: :abbyy-rtr-sdk-1.0 обычно вызывает неверный путь, имя файла или отсутствие ext: 'aar'.

Ресурсы dictionaries и patterns копируются согласно нужным языкам и профилям. Пропущенный ресурс проявляется не при компиляции, а при запуске конкретного распознавания. Поэтому автоматический тест должен открыть каждый поддерживаемый сценарий на собранном release-варианте, где правила shrinking и packaging отличаются от debug.

Подключение к iOS-проекту

В iOS-проект добавляются AbbyyRtrSDK.framework и AbbyyUI.framework, а путь к каталогу libs включается в Framework Search Paths. Для поставки с несколькими архитектурами используется copy_frameworks.sh: скрипт удаляет лишние срезы и подписывает результат перед загрузкой в магазин.

Ресурсный скрипт copy_assets.py копирует словари и шаблоны в нужные каталоги. Его запускают на фазе сборки после проверки пути к assets. Если разработчик переместил папку, скрипт может завершиться без ожидаемых файлов; полезно явно проверять наличие ключевого ресурса и останавливать сборку с понятным сообщением.

MobileCapture.License добавляется в Copy Bundle Resources. Наличие файла в дереве Xcode ещё не гарантирует попадание в конкретный target: справа должна быть отмечена Target Membership. При нескольких приложениях и расширениях лицензию включают только туда, где работает распознавание.

В инструкции для этой интеграции Bitcode отключается. В старых проектах параметр мог оставаться включённым по шаблону, что приводило к ошибке линковки или публикации. После изменения проверяют archive-сборку, потому что симулятор и обычный запуск не повторяют все действия App Store-пайплайна.

Симулятор удобен для проверки React Native и навигации, но не заменяет реальное устройство при тестировании камеры, производительности и автофокуса. Минимально проверяют несколько поколений iPhone, портретную и альбомную ориентацию, отказ в разрешении, сворачивание приложения и возврат во время открытой камеры.

Интеграция через React Native

React Native-модуль предоставляет JavaScript-функции startImageCapture, recognizeText, extractData, detectDocumentBoundary, cropImage, rotateImage, assessQualityForOcr, exportImage и exportImagesToPdf. За ними находятся нативные реализации, поэтому одного пакета из npm недостаточно: проекту нужны библиотеки, ресурсы и лицензия для каждой платформы.

startImageCapture возвращает Promise. Вызов оборачивают в try/catch, а кнопку блокируют до завершения, чтобы пользователь не открыл два контроллера камеры. После размонтирования экрана результат не должен менять уже уничтоженное состояние; удобно хранить флаг активности или отменять переход.

Большие изображения не следует переводить через мост в Base64. Файловый URI уменьшает копирование и позволяет загружать документ потоково. Если серверная библиотека требует Blob, файл читают порциями нативным модулем или подходящим файловым API.

Параметры проверяют в JavaScript до нативного вызова. Например, Base64 допустим только для одной страницы, неизвестное значение exportType следует отклонить сразу, а путь PDF — подготовить в доступном каталоге. Это даёт понятную ошибку возле формы вместо общего исключения из Objective-C или Java.

При обновлении React Native отдельно проверяют совместимость Gradle, CocoaPods, AndroidX и механизмов автолинковки. Ошибка после перехода на новую сборочную цепочку не всегда связана с OCR; сначала собирают минимальный пример, сравнивают версии плагина и шаблона, затем переносят изменения в основной проект.

Cordova, Xamarin и другие оболочки

Для Cordova применялся отдельный плагин, который также ожидает AAR, iOS frameworks, assets и лицензию. Конфигурация выполняется в нативных каталогах платформ, а при повторном добавлении platform эти файлы могут быть удалены. Поэтому копирование лучше автоматизировать hook-скриптом или процессом CI.

В Xamarin связываются нативные библиотеки и их API, а интерфейс камеры вызывается из общего кода через платформенные службы. Особое внимание уделяют жизненному циклу Activity и UIViewController: результат нельзя отправлять в страницу, которая уже закрыта из-за поворота или навигации.

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

При выборе современного фреймворка нужно оценить доступность поддерживаемого моста. Наличие старого публичного примера доказывает принцип интеграции, но не гарантирует совместимость с каждой новой версией Flutter, .NET MAUI или React Native. Иногда надёжнее написать небольшой собственный мост над нативным API.

Для диагностики сохраняют нативный stack trace, а не только сообщение JavaScript. Иначе ошибка линковки, отсутствующий ресурс и отказ лицензии выглядят одинаково как rejected Promise. В production-логах персональные изображения и распознанный текст маскируются.

Уменьшение размера приложения

На размер влияют нативный код, архитектуры процессоров, словари, шаблоны и готовые профили. Если требуется только захват и выравнивание изображений, ресурсы OCR не нужны. Если распознаётся один язык, не следует включать все словари. Если приложение выпускается только для современных ARM64-устройств, лишние ABI можно исключить при условии требований магазина и парка устройств.

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

Android App Bundle распределяет нативные библиотеки по ABI, поэтому размер скачивания меньше общего APK. Однако assets могут попадать во все варианты. Разделение языковых ресурсов по динамическим модулям возможно только если библиотека умеет находить их после установки; без подтверждения лучше не усложнять загрузку.

На iOS удаление неактивных архитектур скриптом важно не только для размера, но и для корректной публикации. Ресурсы можно отфильтровать до сборки. После оптимизации сравнивают не только размер архива, но и время первого запуска, пиковую память и скорость открытия камеры.

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

Производительность и память

Главные потребители ресурсов — камера, декодирование больших изображений, перспективное преобразование и OCR. Одновременный запуск нескольких операций создаёт конкуренцию за память и процессор. Обработку страниц лучше ставить в последовательную очередь, а интерфейс обновлять после каждого завершённого шага.

4K-кадр в несжатом виде занимает десятки мегабайт, даже если JPEG на диске весит несколько мегабайт. При повороте и обрезке могут существовать две или три копии. На Android это приводит к OutOfMemoryError, на iOS — к завершению процесса системой. Ограничение размера галереи и файловые URI напрямую уменьшают риск.

Автоспуску нужна стабильная частота предпросмотра. Если OCR одновременно обрабатывает каждый кадр, камера начинает запаздывать и подсказка Keep still появляется поздно. Для документа сначала получают качественный снимок, затем запускают тяжёлое распознавание; real-time режим ограничивают областью и частотой.

Сжатие выполняют один раз в конце. Повторное сохранение JPEG после обрезки, затем после поворота и снова перед загрузкой накапливает артефакты. Лучше сохранять промежуточный результат без лишнего перекодирования и применять выбранную степень при экспорте.

Замеры проводят на слабом поддерживаемом устройстве. Среднее время на флагмане не показывает задержки у большинства пользователей. Измеряют открытие камеры, время до рамки, момент автоспуска, обрезку, OCR, экспорт PDF и отправку, отдельно фиксируя размер документа и разрешение.

Конфиденциальность и хранение документов

Распознавание и обработка могут выполняться на устройстве, поэтому изображение не обязано уходить во внешний OCR-сервис. Но итоговая конфиденциальность зависит от приложения: оно само выбирает каталог, журнал, аналитику и сервер. Нельзя обещать офлайн-режим всей системы только на основании возможностей движка.

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

Снимки не включают в отчёты об ошибках автоматически. Crash-система должна получать код операции, модель устройства и stack trace, но не содержимое Base64, OCR-текст или путь с именем клиента. Для добровольной отправки примера нужен отдельный экран согласия и очистка чувствительных полей.

Лицензионный файл является частью защищённой поставки и не должен публиковаться в открытом репозитории. Публичные примеры специально не содержат native assets и лицензии. В CI секреты получают из закрытого хранилища, копируют перед сборкой и удаляют из рабочей папки после job.

Сервер должен принимать только ожидаемые типы и размеры. Расширение .jpg не гарантирует формат, поэтому проверяют сигнатуру, декодирование и лимиты. PDF сканируют на корректность и количество страниц, а пользовательский идентификатор передают отдельно, не извлекая его из имени файла.

Практический сценарий: удалённая регистрация клиента

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

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

После кадра выполняются обрезка, оценка качества и профильное извлечение. На экране подтверждения поля сгруппированы по смыслу, рядом с каждым показывается вырезка. Пользователь исправляет только сомнительные значения; уверенные данные всё равно можно раскрыть для проверки.

Даты проверяются на диапазон и взаимную логику, номера — на длину и контрольные правила, имя — на допустимые символы. Ошибка бизнес-валидации не должна инициировать повторный OCR автоматически: сначала объясняется, какое поле не прошло проверку, затем предлагается исправление или пересъёмка.

На сервер отправляются выровненные изображения, подтверждённые данные, показатели качества и версия схемы полей. Так изменение интерфейса в будущем не разрушит обработку старых заявок.

Практический сценарий: страховой пакет и многостраничные формы

В страховом заявлении число листов заранее неизвестно, поэтому requiredPageCount оставляют нулём. Счётчик показывает накопленные страницы, кнопка редактора доступна после первого кадра, а завершение требует явного подтверждения Все страницы добавлены.

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

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

Если связь пропала, пакет остаётся в защищённом локальном хранилище со статусом ожидает отправки. Повторная попытка использует идемпотентный идентификатор, чтобы сервер не создал две заявки. Удаление локальных файлов происходит только после подтверждения принятия всех частей.

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

Практический сценарий: реквизиты, IBAN и визитные карточки

Для банковских реквизитов достаточно одной страницы или области счёта. Профиль IBAN извлекает кандидат, после чего приложение удаляет пробелы, приводит буквы к верхнему регистру и проверяет длину и контрольную сумму. Только после успешной проверки значение подставляется в платёжную форму.

Номер карты относится к чувствительным данным. Его нельзя писать в обычный лог, показывать полностью после ухода приложения в фон или сохранять без необходимости. Даже точный OCR не заменяет требования платёжной безопасности и подтверждение пользователя.

Визитная карточка содержит имя, компанию, телефон, электронную почту и адрес. Профиль возвращает компоненты, которые удобно сопоставить с контактом. Перед сохранением пользователь выбирает, какие поля импортировать, и видит предупреждение о возможном дубле.

Для телефона нормализация учитывает код страны и добавочные номера, для почты — допустимый формат, для сайта — безопасную схему. OCR может спутать 1, I и l, поэтому контактные поля проверяются отдельно.

Маленькая визитка требует близкого кадра и правильного documentSize. Если оставить общие настройки A4, карточка займёт недостаточную область и мелкий шрифт потеряется.

Типовые ошибки запуска и лицензии

Сообщение о лицензии чаще всего означает отсутствие MobileCapture.License в конечном bundle/assets, неверное имя или несовпадение параметров. Сначала проверяют release-пакет как архив, затем регистр имени и target membership. Наличие файла в исходной папке ничего не доказывает.

Если AAR не найден, сверяют каталог flatDir, имя без расширения и фактический файл. В многоуровневом проекте $rootDir может указывать не туда, куда ожидает разработчик. Выведите абсолютный путь в Gradle и убедитесь, что CI копирует библиотеки до этапа dependency resolution.

UnsatisfiedLinkError на Android указывает на отсутствующую ABI или нативную зависимость. Сравнивают архитектуру устройства с содержимым APK/AAB и проверяют libc++_shared.so. Ошибка только в эмуляторе часто связана с исключённым x86_64.

На iOS undefined symbols или framework not found исправляются проверкой Framework Search Paths, Link Binary With Libraries и фаз скриптов. Ошибка при архивировании, но не при запуске, часто означает архитектуры или подпись после копирования framework.

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

Типовые ошибки камеры и качества

Чёрный экран при открытии камеры проверяют по порядку: разрешение, наличие камеры на устройстве, жизненный цикл Activity/контроллера, конкурирующее приложение, ориентация и ошибка инициализации. Лог с момента открытия важнее снимка чёрного экрана.

Если автоматический спуск не происходит, уменьшите порог размера документа, уберите слишком узкое соотношение сторон и проверьте освещение. Ручная кнопка помогает определить, работает ли сама камера. Если ручной кадр получается, проблема обычно в критериях автоопределения, а не в разрешении.

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

Размытый текст исправляется пересъёмкой, а не максимальным фильтром. Дождитесь фокуса, удерживайте телефон, увеличьте документ и используйте FullHD или 4K для мелкого шрифта. На старом устройстве слишком высокое разрешение может снизить стабильность, поэтому сравните режимы.

Блик от ламинации уменьшается наклоном документа и отключением фонарика. Тень от телефона — сменой направления света. Эти подсказки полезно показывать до третьей неудачной попытки, когда система уже видит повторяющийся низкий показатель качества.

Типовые ошибки OCR и извлечения полей

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

Смешение кириллицы и латиницы заметно в именах и кодах. Для отображения строка выглядит одинаково, но серверная проверка отклоняет символ. Нормализацию выполняют только в полях с известным алфавитом и сохраняют исходный результат для аудита.

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

Неверный профиль даёт правдоподобные, но не те поля. Тип документа должен выбираться до извлечения либо определяться надёжным классификатором. Не запускайте все профили и не принимайте первый непустой ответ.

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

Тестирование перед выпуском

Набор тестов должен отражать реальные документы: новые и потёртые, белые и цветные, мелкий шрифт, печати, рукописные пометки, ламинация, складки, разные языки. Идеальные распечатки проверяют только базовую работоспособность.

Для камеры создают матрицу устройств, освещения, фона, ориентации и расстояния. Измеряют долю автоматических срабатываний, число пересъёмок, время до первого кадра и частоту ручной коррекции. Эти метрики показывают удобство лучше субъективного работает быстро.

OCR оценивают по полям, а не только по символам. Ошибка в номере договора важнее пропущенной точки в примечании. Для каждого поля задают допустимость автоматического принятия, ручной проверки или обязательной пересъёмки.

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

Release-сборка тестируется отдельно: shrinking, подпись, ABI-фильтры, копирование assets и разрешения могут отличаться. Обязателен сценарий чистой установки без предварительно выданных разрешений и без файлов от старой версии приложения.

Сравнение ABBYY Mobile Capture с аналогами

Решения ниже относятся к встраиваемому захвату документов, но акценты различаются. ABBYY Mobile Capture сочетает автоматическую съёмку, обработку, OCR и профильное извлечение; другие продукты могут предлагать более широкий набор платформ, готовый searchable PDF, активную современную сборочную цепочку или только базовый сканер.

ПрограммаЛучше подходит дляГлавное ограничение
ABBYY Mobile CaptureЗахват документов, OCR и профильные поля на iOS/AndroidНужны нативные библиотеки, ресурсы и лицензия
Scanbot Document Scanner SDKСовременный сканер с фильтрами, review-экранами, PDF/TIFF и дополнительными модулямиРасширенные функции распределены по лицензируемым модулям
Docutain SDKСканирование, searchable PDF и извлечение данных на мобильных и настольных платформахНабор готовых полей зависит от выбранного пакета
Google ML Kit Document ScannerБыстрое добавление готового потока сканирования в Android-приложениеСканер документов доступен только на Android и загружается через Google Play services
Google ML Kit Text RecognitionБесплатное распознавание строк и координат в собственном интерфейсеНе даёт полного редактора многостраничных документов и профильного извлечения ABBYY

Как выбрать подходящий инструмент

ABBYY Mobile Capture имеет смысл выбирать для проекта, где уже получены совместимые нативные компоненты и важны не только снимки, но и текст, координаты, пользовательские шаблоны или готовые профили документов. Команда должна быть готова поддерживать нативную интеграцию и тщательно зафиксировать рабочие версии сборочных инструментов.

Scanbot лучше подходит, когда требуется активно поддерживаемый сканер с широкой экосистемой, review-экранами, фильтрами и готовым searchable PDF. Docutain удобен, если нужен единый поставщик для мобильных и настольных платформ, OCR и распространённых финансовых полей.

ML Kit Document Scanner рационален для Android, когда нужен готовый поток с минимальным увеличением приложения и приемлема зависимость от Google Play services. ML Kit Text Recognition выбирают для собственного интерфейса и базового OCR, если команда сама реализует границы, редактор, PDF и проверку структурированных полей.

PDF Commander решает другую задачу: пользователь уже имеет PDF и хочет редактировать его на компьютере. Он подходит для ручной работы с готовыми файлами, но не заменяет SDK, который встраивается в мобильную форму и управляет камерой.

Выбор проверяют прототипом на реальных документах. Маркетинговый список функций не показывает точность на конкретном бланке, время обработки на слабом телефоне и сложность сборки.

Контрольный список рабочей интеграции

До открытия камеры определены тип документа, число страниц, ориентация, разрешение, доступность галереи и требования к качеству. Пользователь видит короткую подготовительную инструкцию, а запрос разрешения объясняет назначение камеры.

Во время съёмки рамка не перекрывает важные элементы, подсказки локализованы, ручной спуск и фонарик доступны согласно сценарию, выход из непустой сессии подтверждается понятным диалогом. Автоспуск проверен на разных фонах и устройствах.

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

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

Сборка содержит правильные AAR/framework, ABI и assets, лицензия находится в конечном пакете, разрешения описаны, release-вариант проверен. Логи не содержат документов, Base64 и персонального текста.

Перед выпуском измерены точность, время, память, размер файлов и число пересъёмок. Настроены повторная отправка, удаление временных файлов и серверная проверка формата. Такой контроль превращает демонстрационный вызов камеры в устойчивый производственный процесс.

Дополнительные меры надёжности

При приёмке результата полезно вычислять SHA-256 файла и сохранять его вместе с идентификатором операции. Хеш не раскрывает содержимое документа, но позволяет доказать, что переданный на сервер файл совпадает с подтверждённым пользователем и не был заменён при повторной отправке.

Времена операций лучше записывать раздельно: ожидание разрешения, открытие камеры, поиск границ, удержание до автоспуска, обработка, OCR, экспорт и сеть. Один общий таймер скрывает причину задержки и мешает понять, нужно ли менять подсказку, разрешение или сервер.

Для доступности кнопки получают текстовые метки, достаточный размер касания и порядок фокуса. Рамка документа не должна быть единственным цветовым сигналом; подсказка голосом или текстом помогает пользователю со сниженным зрением понять, найден ли лист и требуется ли приблизиться.

При уходе приложения в фон камера должна остановиться, а при возврате — безопасно восстановиться или начать с понятного экрана. Продолжение старого видеопотока без проверки разрешения и контроллера приводит к чёрному кадру и утечке ресурсов.

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

Серверный API должен возвращать идентификатор принятой страницы и итогового документа. Клиент сверяет количество, а затем помечает локальную сессию завершённой. Ответ HTTP без проверки тела недостаточен: сервер мог принять запрос, но отклонить один файл после валидации.

Для нестабильной сети используется экспоненциальная задержка и ограниченное число автоматических повторов. Ошибки авторизации и формата не повторяют бесконечно; они требуют обновления токена или вмешательства пользователя.

При изменении языка во время открытой камеры безопаснее закрыть контроллер и открыть заново с новым bundle строк. Частичная замена ресурсов создаёт смешанный интерфейс, где камера переведена, а редактор остаётся на прежнем языке.

Для аналитики достаточно событий камера открыта, автоспуск, ручной спуск, пересъёмка, ручная обрезка, отмена, OCR принят и код ошибки. Содержимое документа, распознанные строки и точные пути не собираются.

Контроль дублей можно строить по perceptual hash уменьшенной выровненной страницы. Точный SHA-256 не обнаружит второй кадр того же листа с небольшим сдвигом, а визуальный хеш поможет предложить удалить повтор перед формированием PDF.

Если пользователь снимает оборот карточки, интерфейс должен явно назвать требуемую сторону. Одинаковая камера без контекста приводит к повторной съёмке лицевой стороны и ошибке комплекта, которую OCR не всегда способен определить.

При серверной классификации полезно передавать исходный размер, размеры после обрезки, угол поворота и показатели качества. Эти данные помогают отличить ошибку классификатора от плохого мобильного кадра и подобрать правила повторной съёмки.

Поля со строгой контрольной суммой можно принимать автоматически только после проверки. Поля без формальной проверки, например фамилия, требуют порога уверенности и визуального подтверждения. Универсальная стратегия для всех типов данных создаёт либо лишние проверки, либо скрытые ошибки.

Тестовый стенд должен уметь подменять камеру набором изображений для воспроизводимых проверок Core API. Отдельно остаются инструментальные тесты реальной камеры, где оцениваются фокус, стабилизация и пользовательские движения.

Файлы экспорта именуют случайным идентификатором, а не распознанным ФИО или номером документа. Это снижает утечку через журналы, резервные копии и список недавних файлов. Человекочитаемое имя можно присвоить только при явном сохранении пользователем.

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

После обрезки сохраняется EXIF-ориентация либо пиксели физически поворачиваются. Смешение этих подходов приводит к тому, что один просмотрщик показывает страницу правильно, а OCR или сервер — боком. Нормализованный файл предпочтительнее скрытой метки.

Для печатей и подписей цветной оригинал сохраняют даже при создании чёрно-белой копии для OCR. Бинаризация улучшает текст, но может уничтожить оттенки и тонкие линии, необходимые для визуальной проверки.

При многостраничном PDF размеры страниц задают последовательно. Если один кадр получает пиксельный размер, а другой физический, просмотрщик показывает резкие скачки масштаба. Нормализация к A4 или фактическому documentSize делает документ предсказуемым.

Ограничение максимального числа страниц защищает от случайной бесконечной съёмки и переполнения памяти. Даже в режиме requiredPageCount=0 приложение может установить собственный предел и предложить начать второй документ.

При приёмке результата полезно вычислять SHA-256 файла и сохранять его вместе с идентификатором операции. Хеш не раскрывает содержимое документа, но позволяет доказать, что переданный на сервер файл совпадает с подтверждённым пользователем и не был заменён при повторной отправке.

Приёмочные проверки конфигурации

Лицензию проверяют в двух вариантах: чистая установка и обновление поверх предыдущей сборки. В первом случае камера должна открыться после копирования MobileCapture.License в конечный bundle или assets; во втором нельзя полагаться на файл, оставшийся от старой версии. Отдельно фиксируют понятное сообщение для пользователя, если движок не инициализирован, и отсутствие технического пути к лицензии в журнале интерфейса.

Ресурсы OCR тестируют не по наличию каталога в исходном проекте, а по фактическому содержимому готового APK, AAB или IPA. Для каждого заявленного языка запускают один короткий и один многострочный образец, затем намеренно удаляют словарь из тестовой сборки и убеждаются, что ошибка диагностируется до отправки документа. Это выявляет ошибочные правила упаковки и случайное удаление ресурсов оптимизатором.

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

Автоматический захват испытывают на белом столе, тёмной поверхности, бликующей ламинации и при частичном выходе листа из кадра. Ожидается, что контур не фиксируется на фоне, подсказка меняется в соответствии с причиной плохого кадра, а ручная кнопка остаётся доступной согласно настройке. Для слабого устройства отдельно измеряют задержку между стабильным контуром и сохранением снимка.

Импорт из галереи проверяют на JPEG и PNG с разными ориентационными метаданными, на изображении больше установленного лимита и на повреждённом файле. После обработки страница должна иметь правильный поворот, а отказ — возвращать контролируемый результат без пустого элемента в списке. Максимальный размер изображения тестируют на границе значения, а не только на явно маленьком и огромном файле.

Многостраничный режим проходит сценарии с точным числом страниц, неограниченным набором, удалением середины и повторной съёмкой выбранной страницы. Кнопка завершения должна активироваться только при допустимом количестве кадров, а порядок страниц сохраняться после редактирования. Отмена на экране камеры и закрытие редактора проверяются отдельно, поскольку эти пути возвращают разные состояния и требуют разной очистки временных файлов.

Вывод File и Base64 тестируют раздельно. Для одной страницы Base64 сверяют по декодированию и сигнатуре формата; для нескольких страниц приложение не должно пытаться удерживать все изображения строками в памяти. Файловый результат проверяют на существование, права чтения и удаление после успешной передачи. Ошибка записи в заполненное хранилище должна возвращаться до перехода к следующему экрану.

Экспорт JPG, PNG и PDF проверяют не только по расширению. JPEG должен открываться после выбранного уровня сжатия, PNG — сохранять ожидаемую геометрию, а PDF — содержать все страницы в заданной последовательности и с корректным размером. Отдельный тест подтверждает, что поиск текста в таком PDF не появляется автоматически: OCR-результат нужно сохранять и связывать с документом явно, если это требуется процессу.

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

Android-сборки проверяют на каждой включённой ABI: armeabi-v7a, arm64-v8a, x86 и x86_64 либо на явно утверждённом подмножестве. Тестовый стенд должен обнаруживать отсутствие нативной библиотеки до выпуска, а не по отчёту пользователя. Дополнительно сравнивают размер AAB и содержимое split APK, чтобы правила фильтрации не исключили движок, UI-компонент или libc++_shared для конкретной архитектуры.

iOS-проверка включает сборку для устройства, архивирование и установку из экспортированного пакета. Успешный запуск из Xcode недостаточен: скрипт удаления лишних архитектур и подписи framework выполняется именно на archive-пути. После установки камера, галерея и ресурсы OCR должны работать без Framework not found, а MobileCapture.License обязан находиться в Copy Bundle Resources конечной цели.

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