【ライブラリを使おう-ZXing】QRコードを読み取る

このエントリーを Google ブックマーク に追加
Pocket
[`yahoo` not found]

今回はAndroidでZXing ライブラリを使ってQRコードを読み取る方法をメモします。
まず、core.jarとjavese.jarをダウンロードします。
本当はGitHubからダウンロードすべきなのですが、jarファイルがなくなっためMavenから取得します。 上の二つのjarをAndroidStudioProjectのlibsフォルダにコピーしてください。
プロジェクトをビルドしなおすと準備は完了です。
下記のコードは画面をタッチするとオートフォーカスが動き、オートフォーカスが完了するとQRコードを読み込みます。
public class ReaderActivity extends Activity {

    private Camera mCamera;

    private SurfaceView mSurfaceView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_reader);
        mSurfaceView = (SurfaceView) findViewById(R.id.preview);
        SurfaceHolder holder = mSurfaceView.getHolder();
        holder.addCallback(new SurfaceHolder.Callback() {
            @Override
            public void surfaceCreated(SurfaceHolder holder) {
                int cameraId = getCameraId();
                mCamera = Camera.open(cameraId);
                if (mCamera != null) {
                    setCameraDisplayOrientation(ReaderActivity.this, cameraId, mCamera);
                    try {
                        mCamera.setPreviewDisplay(holder);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }

            @Override
            public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
                if (mCamera != null) {
                    mCamera.startPreview();
                }
            }

            @Override
            public void surfaceDestroyed(SurfaceHolder holder) {
                if (mCamera != null) {
                    mCamera.stopPreview();
                    mCamera.release();
                    mCamera = null;
                }
            }
        });
    }
    
    private int getCameraId() {
        // 端末に搭載されているカメラの数を取得
        int numberOfCameras = Camera.getNumberOfCameras();
        int cameraId = 0;
        // 各カメラの情報を取得
        for (int i = 0; i < numberOfCameras; i++) {
            Camera.CameraInfo caminfo = new Camera.CameraInfo();
            Camera.getCameraInfo(i, caminfo);
            // カメラの向きを取得
            int facing = caminfo.facing;
            if (facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
                cameraId = i;
                break;
            }
        }
        return cameraId;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (mCamera != null &amp;&amp; event.getAction() == MotionEvent.ACTION_DOWN) {
            mCamera.autoFocus(autoFocusCallback);
        }
        return super.onTouchEvent(event);
    }

    public static void setCameraDisplayOrientation(Activity activity, int cameraId, Camera camera) {
        Camera.CameraInfo info = new Camera.CameraInfo();
        Camera.getCameraInfo(cameraId, info);
        int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();
        int degrees = 0;
        switch (rotation) {
            case Surface.ROTATION_0:
                degrees = 0;
            break;
            case Surface.ROTATION_90:
                degrees = 90;
            break;
            case Surface.ROTATION_180:
                degrees = 180;
            break;
            case Surface.ROTATION_270:
                degrees = 270;
            break;
        }
        int result;
        if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
            result = (info.orientation + degrees) % 360;
            result = (360 - result) % 360;  // compensate the mirror
        } else {  // back-facing
            result = (info.orientation - degrees + 360) % 360;
        }
        camera.setDisplayOrientation(result);
    }

    private Camera.AutoFocusCallback autoFocusCallback = new Camera.AutoFocusCallback() {
        @Override
        public void onAutoFocus(boolean success, Camera camera) {
            if (!isFinishing() &amp;&amp; success) {
                camera.setOneShotPreviewCallback(previewCallback);
            }
        }
    };

    private PreviewCallback previewCallback = new PreviewCallback() {
        @Override
        public void onPreviewFrame(byte[] data, Camera camera) {
            // 読み込む範囲
            int previewWidth = camera.getParameters().getPreviewSize().width;
            int previewHeight = camera.getParameters().getPreviewSize().height;
            // プレビューデータから BinaryBitmap を生成
            PlanarYUVLuminanceSource source =
            new PlanarYUVLuminanceSource(data, previewWidth, previewHeight, 0, 0, previewWidth, previewHeight, false);
            BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
            // バーコードを読み込む
            Reader reader = new MultiFormatReader();
            String text = null;
            try {
                text = reader.decode(bitmap).getText();
            } catch (Exception e) {
            }
            if (text != null) {
                Toast.makeText(getApplicationContext(), text, Toast.LENGTH_SHORT).show();
            } else {
                Toast.makeText(getApplicationContext(), "Not Found", Toast.LENGTH_SHORT).show();
            }
        }
    };
}

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

*

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)