Android + zxingでQRコード読み取り

androidでQRコードを読み取るのはZXingという
Apache License v2.0で公開されているライブラリがよく使われているようなのですが
シンプルなサンプルコードを見つけられなかったのでまとめました。
zxing ≫ https://github.com/zxing/zxing

環境
・OS X 10.9.5
・Android Studio 1.1.0

開発環境設定
AndroidStudioはライブラリを取り込むときに色々方法があるみたい
参考 ≫ http://sakebook.hatenablog.com/entry/2014/08/17/004540

今回はこちらを参考に、外部のリポジトリからローカルに取り込む方法でやってみた。
Android StudioでZXingを使う ≫ http://moxxxc.hatenablog.com/entry/2015/01/26/230127

一連の流れ
・先のリンクで紹介されているIntentIntegratorを使う方法(フルスクリーンでQRreadカメラが起動する)はお手軽だけど、カメラサイズの変更など細かい設定ができなさそう。
・カメラを縦表示とか、全画面表示じゃなくしたいとか、もっと細かい所をやろうとする場合、カメラから取得した画像をBinaryBitmap化して、com.google.zxing.qrcode.QRCodeReaderに投げ、読み取り結果を得るというフローをやらないといけない様。

以下、カメラプレビューをSurfaceViewに描写&毎フレームQRを読み取り結果を得るサンプル

package com.test;

import android.content.Context;
import android.hardware.Camera;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

import com.google.zxing.BinaryBitmap;
import com.google.zxing.PlanarYUVLuminanceSource;
import com.google.zxing.Reader;
import com.google.zxing.Result;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.qrcode.QRCodeReader;

import java.io.IOException;

public class QRCameraView extends SurfaceView implements SurfaceHolder.Callback, Camera.PreviewCallback {

    private Camera _camera;

    public QRCameraView(Context context) {
        super(context);
        getHolder().addCallback(this);
    }

    //SurfaceViewが作られたタイミング
    @Override
    public void surfaceCreated(SurfaceHolder holder) {

        //カメラをopen Camera.open(1)とかやると、全面カメラなど、どのカメラを使うか指定できる 
        _camera = Camera.open();

        //カメラのプレビュー用のviewをこのSurfaceViewに設定
        try {
            _camera.setPreviewDisplay(holder);
        } catch (IOException e) {
            e.printStackTrace();
        }

        //カメラの映像が更新される毎に実行されるcallBackを設定
        _camera.setPreviewCallback(this);

        //映像取得スタート
        _camera.startPreview();

    }

    //SurfaceViewが破棄されたタイミング
    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {

        //削除処理
        _camera.cancelAutoFocus();
        _camera.release();
        _camera = null;

    }

    @Override
    public void onPreviewFrame(byte[] data, Camera camera) {

        int previewWidth = camera.getParameters().getPreviewSize().width;
        int previewHeight = camera.getParameters().getPreviewSize().height;

        PlanarYUVLuminanceSource source = new PlanarYUVLuminanceSource(
                data,
                previewWidth,
                previewHeight,
                0,
                0,
                previewWidth,
                previewHeight,
                false
        );

        BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));

        Reader reader = new QRCodeReader();
        Result result = null;

        try {
            
            result = reader.decode(bitmap);
            //成功した場合、読み取り結果が文字列で取得できる
            String text = result.getText();
            Log.d("result",text);
            
        } catch (Exception e) {

            //読み取れなかったとき
            Log.d("result","no read....");
            
        }
    }

}


QRCodeReader以外にも1次元バーコードとか読める用のもあったり、全部のパターンよめるMultiReader的なのもあるみたい。
ただ用途は絞った方が精度が高いイメージ。IntentIntegratorの方で特徴点?みたいなのがピピピと出てたのでそれとかも実装できるのかな。