Как мы QR-коды распознавали

Совсем недавно я завершил работу над приложением Рамлер-Касса: Терминал. Основная его задача — распознавание билетов посетителей кинотеатра. Изначально для этой цели использовались нативные средства, предоставляемые iOS (AVFoundation.framework). Проблемы проявились при попытке сканирования QR-кода из Passbook — приложение распознавало его только при минимальном уровне яркости экрана. Здесь-то и началось самое веселое.

Путей решения возникшей задачи было два:

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

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

IMG_3228

То самое «ярко-освещенное помещение»

К зафиксированному на hand-made подставке iPad 2 (именно такие устройства используются в данный момент в кинотеатрах) на разном удалении подносились следующие устройства: iPhone 5, Nexus 5, и Samsung неизвестной модели, но с экраном 320×240 пикселей. Расстояние и угол, с которых начиналось распознавание, фиксировались с помощью специально расчерченного листа бумаги и заносились в таблицу:

Screenshot 2014-09-04 10.18.06

Обойдемся простым скриншотом

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

Частых и быстрых считываний вам 😉