July 10, 2013 · Android

Zxing(2.2)でQRコードを読み取る

さて、今回は、AndriodでQRコードを読み取る処理を紹介します。

ZxingというGoogle謹製のLibraryを利用していきます。

尚、Androidに限らずiOSやC++/C#などのさまざまな
プラットフォーム向けになっています。

また、QRコードの2次元バーコードのみならず
慣れ親しんだ1次元バーコードでも読み取ることができます。
AndroidでQRコードの読み取り処理は
Zxingの一択と考えても過言では無いかと思います。

Zxing
https://code.google.com/p/zxing/

私の開発環境は、以下のようになっています。

OS: OS X
IDE: Android Studio (0.2.2)
NDK: Android NDK r8e (Install Path: /Applications/android-ndk-r8e)

Zxingを紹介している、他の技術ブログを見ていると
以下のリンクからZXing-2.x.zipをDownloadしてから自分のプロジェクトに
取り込むように紹介しているところが多くみられます
https://code.google.com/p/zxing/downloads/list

せっかく、Android Studio + Gradleを利用しているので
もっとスマートで手軽にするために、Gradleに取り込ませましょう

Zxingの中で、「GettingStarted」というページがあります
https://code.google.com/p/zxing/wiki/GettingStarted

ここでは、Mavenのpom.xml設定が書いてありましたが
残念なことにGradleのことには書いてありませんでした。
でも、大して難しいことはしませんし、Mavenよりも少しシンプルに書くことが出来ます

例えば、
Mavenの場合 (pom.xml)

<dependencies>  
    ...
    <dependency>
      <groupId>com.google.zxing</groupId>
      <artifactId>core</artifactId>
      <version>2.2</version>
    </dependency>
    ...
  </dependencies>

このようになりますが…

Gradleの場合 (build.gradle)

dependencies {  
  // Zxing QR Code Library
  compile group: 'com.google.zxing', name: 'core', version: '2.2'
}

これだけで済みます。
build.gradleの dependenciesに追記するだけで
Android Studioの「Project Settings」を変更する必要はありません。

さて、本題は使い方ですね。
以下のサンプルでは、Zxingで取得したデータをダイアログで表示するようにしています。

CameraクラスのsetPreviewCallback(_previewCallback)を用いて
onPreviewFrameで、引数に渡されるYUV形式のバイトデータを
PlanarYUVLuminanceSourceに渡してあげます

ただ、PlanarYUVLuminanceSourceのコンストラクタには引数が多いので、簡単な説明をします。

/**
 * 第1. byte[]の YUVデータ
 * 第2. 画像データの width
 * 第3. 画像データの height
 * 第4. 開始 X 座標
 * 第5. 開始 Y 座標
 * 第6. 読み取る範囲 width
 * 第7. 読み取る範囲 height
 * 第8. データを反転するか否か (フロントカメラの場合は true)
 */
PlanarYUVLuminanceSource source = new PlanarYUVLuminanceSource(  
          data, size.width, size.height, 0, 0, size.width, size.height, false);

第4から第7までを1つのRectクラスで渡せるようにしてくれたらいいのに、Google様…
と思ったんですが、ここは従うしかありません。

それ以外のクラスについては、見ていただくだけで、何してるか理解が出来るものだと思います
サンプルソースの抜粋

  private PreviewCallback _previewCallback = new PreviewCallback() {
    @Override
    public void onPreviewFrame(byte[] data, Camera camera) {

      if (mDialog.isShowing()) return;

      // Read Range
      Camera.Size size = camera.getParameters().getPreviewSize();

      // Create BinaryBitmap
      PlanarYUVLuminanceSource source = new PlanarYUVLuminanceSource(
          data, size.width, size.height, 0, 0, size.width, size.height, false);
      BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));

      // Read QR Code
      Reader reader = new MultiFormatReader();
      Result result = null;
      String text = null;
      try {

        result = reader.decode(bitmap);
        text = result.getText();

      } catch (NotFoundException e) {
      } catch (ChecksumException e) {
      } catch (FormatException e) {
      } finally {
        if (text != null) {
          mDialog.setMessage(text);
          mDialog.show();
        }
      }
    }
  };

実に簡単に使えるライブラリでしたね。
今回のサンプルプロジェクトもGithubにあげておきましたので、参考にして頂ければと思います。

https://github.com/wasabeef/zxing-QRCode-sample

外部の勉強会も積極的に参加してこうと思うので、機会があればTwitterにでもご連絡ください
@wasabeef_jp