Статьи

Чтение QR-кодов с помощью API Mobile Vision

QR-коды стали вездесущими в последние годы. Я уверен, что вы видели один в газетной рекламе или на рекламном щите. С точки зрения непрофессионала, QR-коды, как и все другие штрих-коды, являются изображениями, которые предназначены для чтения на машинах. Обычно они представляют собой небольшую строку, например сокращенный URL-адрес или номер телефона. Вот пример QR-кода, который содержит URL домашней страницы Tuts +:

Tuts + URL как QR-код

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

Последний выпуск SDK для сервисов Google Play включает в себя API для мобильных устройств, который, помимо прочего, позволяет разработчикам Android легко создавать приложения, способные обнаруживать и считывать QR-коды в режиме реального времени. В этом уроке я собираюсь помочь вам начать работу с ним.

Чтобы следовать этому уроку, вам понадобится:

  • последняя версия Android Studio
  • Android-устройство с камерой

Прежде чем использовать API мобильного видения в своем приложении, вы должны добавить SDK 7.8 сервисов Google Play в качестве зависимости compile в build.gradle модуля вашего приложения .

groovy compile 'com.google.android.gms:play-services:7.8.0'

Когда вы нажмете кнопку « Синхронизировать сейчас» , вы увидите ошибку, которая выглядит следующим образом:

Ошибка установки репозитория

Нажмите на ссылку Установить репозиторий и синхронизировать проект, чтобы установить SDK.

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

« `XML

« `

Кроме того, поскольку вы будете использовать камеру устройства для захвата QR-кодов, вам следует запросить разрешение android.permission.CAMERA .

« `XML

« `

Давайте теперь напишем некоторый код, который может считывать QR-код из фотографии, хранящейся в папке ресурсов вашего приложения. Я собираюсь назвать фото myqrcode.jpg . Если у вас нет фотографий, содержащих QR-коды, вы можете получить их у Flickr .

Поскольку API для мобильного видения требует в качестве входных данных Bitmap , сначала необходимо преобразовать фотографию в Bitmap . Для этого откройте фотографию, используя метод AssetManager класса AssetManager и передайте InputStream возвращенный методу BitmapFactory . Для простоты, сделайте это внутри метода onCreate вашей Activity .

java Bitmap myQRCode = BitmapFactory.decodeStream( getAssets().open("myqrcode.jpg") );

Чтобы обнаружить QR-коды (и другие типы штрих-кодов), вы должны использовать экземпляр класса BarcodeDetector . Следующий код показывает, как создать его с помощью BarcodeDetector.Builder :

java BarcodeDetector barcodeDetector = new BarcodeDetector.Builder(this) .setBarcodeFormats(Barcode.QR_CODE) .build();

Обратите внимание, что детектор по умолчанию будет обнаруживать штрих-коды всех поддерживаемых форматов. Я использовал метод setBarcodeFormats чтобы явно указать, что детектор должен обнаруживать только QR-коды.

Используйте Frame.Builder чтобы создать Frame с использованием Bitmap , созданного ранее.

java Frame myFrame = new Frame.Builder() .setBitmap(myQRCode) .build();

Вызовите метод detect BarcodeDetector чтобы сгенерировать SparseArray содержащий все QR-коды, которые BarcodeDetector обнаружил на вашей фотографии.

java SparseArray<Barcode> barcodes = barcodeDetector.detect(myFrame);

Каждый элемент SparseArray содержит объект Barcode . Чтобы получить необработанное содержимое QR-кода, вы можете использовать поле rawValue объекта rawValue . Тем не менее, я предлагаю вам использовать более displayValue для чтения поле displayValue . Вот некоторый код, который печатает содержимое первого QR-кода, обнаруженного API:

« `java // Проверить, был ли обнаружен хотя бы один штрих-код if (barcodes.size ()! = 0) {

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

API мобильного видения также позволяет вам в реальном времени обнаруживать и считывать штрих-коды с помощью камеры вашего устройства. Давайте создадим новую Activity которая делает именно это.

Создайте новый XML-файл макета с именем activity_main.xml . Макет должен иметь SurfaceView для отображения кадров предварительного просмотра, снятых камерой. Если вы хотите, вы также можете добавить TextView для отображения содержимого QR-кодов, которые обнаруживает API.

После использования RelativeLayout для позиционирования обоих виджетов XML-файл макета должен выглядеть примерно так:

« `XML

« `

Создайте новый класс Java с именем MainActivity.java . Сделайте его подклассом Activity и переопределите его метод onCreate . Внутри метода onCreate вызовите setContentView чтобы применить макет, созданный на предыдущем шаге. Затем используйте findViewById чтобы получить ссылки на виджеты, определенные в макете.

« `java setContentView (R.layout.activity_main);

cameraView = (SurfaceView) findViewById (R.id.camera_view); barcodeInfo = (TextView) findViewById (R.id.code_info); « `

Чтобы получить поток изображений с камеры устройства и отобразить их в SurfaceView , создайте новый экземпляр класса CameraSource.Builder с помощью CameraSource.Builder . Поскольку для CameraSource требуется BarcodeDetector , создайте его с BarcodeDetector.Builder класса BarcodeDetector.Builder . При желании вы можете настроить размеры предварительного просмотра камеры с setRequestedPreviewSize метода setRequestedPreviewSize .

« `java barcodeDetector = new BarcodeDetector.Builder (this) .setBarcodeFormats (Barcode.QR_CODE) .build ();

cameraSource = new CameraSource .Builder (this, barcodeDetector) .setRequestedPreviewSize (640, 480) .build (); « `

Затем добавьте обратный вызов в SurfaceHolder SurfaceView чтобы вы знали, когда можно начать рисовать кадры предварительного просмотра. Обратный вызов должен реализовывать интерфейс SurfaceHolder.Callback .

« `java cameraView.getHolder (). addCallback (new SurfaceHolder.Callback () {@Override public void surfaceCreated (SurfaceHolder holder) {}

Внутри метода surfaceCreated метод start объекта CameraSource чтобы начать рисовать кадры предварительного просмотра. Поскольку метод start ожидает, что вы обработаете IOException , вы должны вызывать его из блока try...catch .

java try { cameraSource.start(cameraView.getHolder()); } catch (IOException ie) { Log.e("CAMERA SOURCE", ie.getMessage()); }

Аналогично, внутри метода surfaceDestroyed метод stop объекта CameraSource чтобы прекратить рисование рамок предварительного просмотра.

java cameraSource.stop();

Ваша Activity почти готова. Однако вам все равно нужно сообщить BarcodeDetector что он должен делать при обнаружении QR-кода. Создайте экземпляр класса, который реализует интерфейс Detector.Processor и передайте его методу setProcessor объекта BarcodeDetector . Android Studio автоматически сгенерирует заглушки для методов интерфейса.

« `java barcodeDetector.setProcessor (новый Detector.Processor () {@Override public void release () {}

Внутри метода receiveDetections получите SparseArray объектов Barcode , вызвав метод getDetectedItems класса Detector.Detections . Теперь вы можете написать код, чтобы сделать что-то с обнаруженными QR-кодами, потому что я уже показал вам, как работать с объектами SpareArray ранее в этом руководстве.

Вот как вы можете отобразить displayValue QR-кода в TextView :

« `java final SparseArray barcodes = detections.getDetectedItems ();

if (barcodes.size ()! = 0) {barcodeInfo.post (new Runnable () {// Использовать метод post публичного void runView TextView run () {barcodeInfo.setText (// Обновление TextView barcodes.valueAt (0) ) .displayValue);}}); } « `

Обратите внимание, что вы должны встроить вызов метода setText в вызов метода post из TextView , так как receiveDetections не выполняется в потоке пользовательского интерфейса. Несоблюдение этого требования приведет к ошибке во время выполнения.

Теперь вы можете скомпилировать и запустить ваше приложение. Направьте камеру вашего устройства на QR-код, и вы сможете сразу увидеть его содержимое.

Обнаружение в реальном времени

В этом руководстве вы узнали, как использовать API мобильного видения для считывания QR-кодов со статических изображений, а также из потоков с камер в реальном времени. Хотя в этом руководстве мы работали только с QR-кодами, вы также можете использовать API для чтения других популярных форматов штрих-кодов, таких как UPC-A и EAN-13.

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