Содержание
Коротко
Автор выложил в npm пакет react-native-glyph-ocr: распознавание текста прямо на устройстве для React Native. На iOS работает системный Apple Vision, на Android — PaddleOCR.
На фото этикеток с русским составом Android-ветка читает 77–83% ингредиентов. Обёртки над Google ML Kit на том же наборе дали 13–28%: у Text Recognition v2 нет модели для кириллицы, и русский текст часто «читается» как похожая латиница.
Пакету нужна «новая архитектура» (New Architecture); проверен на React Native 0.85 и 0.87. Для Expo — отдельная сборка для разработки (development build), в Expo Go не заработает.
Что произошло
Нужно было приложение, которое снимает этикетку и разбирает состав. Текст на русском, часто вперемешку с английским, на фольге, мятом пакете, термопечати и даже по дуге банки. Стандартный путь в React Native — обёртки над ML Kit. На латинице они справляются; на кириллице — ломаются: буквы подменяются похожими латинскими, и слово уже не узнать.
На iOS системный Vision с iOS 16 читает русский и украинский без своей модели. Значит, одна библиотека должна скрыть два движка за одним результатом для JavaScript. Автор сначала прогнал спайки на одних фото и одном ручном эталоне: Vision (ревизия 3, режим .accurate, языки ru-RU и en-US) против PaddleOCR PP-OCRv5 mobile на ONNX Runtime с пакетом для восточнославянских языков (eslav: ru, uk, be, en).
Цифры спайков: на обрезанном составе Vision на iPhone 13 Pro Max — около 0,15 с и до 97% ингредиентов; PaddleOCR на Pixel 6a — около 1,1 с и 77–83%. Модели Paddle весят 12,7 МБ один раз; ONNX Runtime добавляет ~33 МБ на архитектуру процессора (ABI). Готовый пакет на TypeScript поверх ONNX автору не подошёл: нужны были кадры камеры и форма результата как у ML Kit, поэтому конвейер на Android написан нативно на Kotlin и C++.
Результат устроен привычно: блоки → строки → слова, уверенность, рамка и угол. Языки задаются при создании экземпляра (createOcr / recognize), модели готовятся один раз (prepare) и кэшируются. Источники — локальные URI, base64, кадр VisionCamera; ссылки http(s) отклоняются намеренно. Есть типизированные ошибки (OcrError) и отмена через AbortSignal. Модели качаются по манифесту с проверкой sha256; можно указать свой сервер или встроить пакеты в сборку.
Для камеры — хук useTextScanner: сначала нативный измеритель (~1 мс) ждёт резкий, неподвижный и достаточно светлый кадр, и только потом один раз запускает распознавание. Перевёрнутый текст на Android решается двойным чтением длинных строк, а не отдельным классификатором ориентации — тот на русских этикетках ошибался слишком часто.
Почему это важно
Представьте кассу самообслуживания, которой подсовывают мятый чек на языке, которого «глаза» камеры не учили. Система не молчит — она уверенно читает чужой алфавит и выдаёт мусор. Именно так ведёт себя ML Kit на кириллице без своей модели: формально ответ есть, смысла в составе продукта — нет.
Для мобильных продуктов с русскими, украинскими и смешанными этикетками это не мелочь интерфейса, а потолок точности. Пока команда тащит облачное распознавание или мирится с 13–28% на устройстве, приложение для состава еды, аптечных вкладышей или документов просто не дотягивает до боевой среды.
Разные движки под одной обёрткой снимают ложную дилемму «либо нативный iOS-код, либо слабый Android». Один API в JavaScript, привычная форма результата для тех, кто уже на ML Kit, и честные цифры по размеру и скорости — так проще спорить на архитектурном разборе, а не на ощущениях.
Цена тоже на виду: на Android тянется ONNX Runtime, набор для замеров узкий (пищевые этикетки), бюджетный телефон пока только оценён по медленным ядрам. Зато альтернатива ExecuTorch (~1,7 МБ) уже в точке входа для разработки — путь к более лёгкой поставке намечен.
На практике
Первый релиз в npm — 0.3.1; до 1.0 API ещё может меняться. Имеет смысл прогнать свой набор фото, а не копировать чужие проценты.
- Установите
react-native-glyph-ocrиreact-native-nitro-modules; на iOS выполнитеpod install. Нужна «новая архитектура» (New Architecture), iOS 16+, Android 7+ (сканер камеры — Android 10+). - В
Expoдобавьте плагин вapp.jsonи соберите сборку для разработки; опцияembedPacks(например["eslav"]) вшивает модели вAPK, чтобы не качать их при первом запуске. - Задайте языки один раз через
createOcr({ languages: ['ru', 'en'] }), вызовитеprepare, затемrecognizeсroi, если состав занимает только часть кадра — так на Android заметно быстрее. - Для живой камеры подключите
VisionCamera5 иuseTextScanner: не распознавайте каждый кадр изonFrameнапрямую — секунда на Android заблокирует поток кадров. - Если сейчас на
@react-native-ml-kit/text-recognition, откройте руководство по переходу в репозитории: форма блоков и строк совместима по идее, меняется движок и подготовка моделей. - Сверьте слабые места на своих данных: коды E читаются хуже (~60%), набор автора — 32 фото этикеток; на другом типе текста цифры будут другими.
- Следите за сообщениями об ошибках и сравнительными тестами в
docs/benchmarks.md: автор планирует замер на бюджетном Android, калибровку порогов сканера по реальным кадрам и возможный переход наExecuTorchпо умолчанию.
Итог
react-native-glyph-ocr закрывает дыру, которую ML Kit оставляет на кириллице: Vision на iOS, PaddleOCR на Android, один результат для JS и пакет уже в npm.
Если приложение читает русские этикетки на устройстве, сравните свой набор фото с обёрткой над ML Kit — разрыв в разы чаще важнее, чем лишние мегабайты нативной среды выполнения.



Комментарии