Zxing 二维码扫描 的简单使用

Zxing 和 Zbar

Zxing 和 Zbar 都是强大的二维码扫描 的开源项目
一开始,我也是很纠结,在网上搜索一番后,发现有以下区别(我也没有深入的使用过,对于各种说法是否准确,也不是很清楚):
1 . Zbar 不能用于商业项目,有版权问题
2 . Zbar 是用 C 语言实现的,效率比 Zing 高
3 . Zbar 内容相对较小,简单(虽然对于我来说都一样,呵呵哒)
4 . Zxing 支持生成二维码,Zbar 不支持

经过激烈的思想斗争,我决定使用 Zxing 。

使用 Zxing 扫描二维码

1 . 添加依赖

 compile 'me.dm7.barcodescanner:zxing:1.9'  

2 . 添加相机的权限

  

3 . 实现 ZXingScannerView.ResultHandler 接口

实现 handleResult 方法

4 . 设置回调

mScannerView.setResultHandler(this);

5 . 开始扫码,设置自动对焦

mScannerView.startCamera();
mScannerView.setAutoFocus(true);

6 . 获取扫描结果

    在 public void handleResult(Result result) 中,也就是第三步骤中实现的接口方法中,传入了一个 result ,扫描的结果就包含在其中,可以通过 result.getText() 获取到扫描的结果。

7 . 停止扫描,一般在 onPause(),或者 onStop() 中调用

mScannerView.stopCamera();

通过相册图片解析二维码

打开相册

Intent imgSelect;
imgSelect = new Intent(Intent.ACTION_GET_CONTENT);
imgSelect.setType("image/*");
startActivityForResult(imgSelect, IMG_REQUEST_CODE);

在 onActivityResult 回调中拿到图片

if (resultCode != RESULT_OK) {
        Toast.makeText(this, "获取图片失败", Toast.LENGTH_SHORT).show();
        return;
    }
    switch (requestCode) {
        case IMG_REQUEST_CODE:
            try {
                //data中带有返回的uri
                Uri photoUri = data.getData();
                Bitmap photoBitmap = null;
                //由于这个方法返回的bitmap没有进行压缩处理,可能会OOM,但是要读取二维码,就不压缩了。
                // 补充,还是要进行压缩,或者判断图片大小,或者裁剪,否则用户点了一个大图,就 OOM 了
                photoBitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), photoUri);
                //下面这个方法是从网上找到,英文文档看不懂,其他的解决方法都是过时的,就这个是好用的
                //来源:http://blog.csdn.net/a102111/article/details/48377537
                //感谢这位作者
                String result = QRCodeUtils.getStringFromQRCode(photoBitmap);
                startResultActivity(result);
            } catch (IOException e) {
                e.printStackTrace();
            }
    }

这里贴一下 解析二维码图片 的两个类

public class ImageUtils {
/**
 * drawableToBitmap with white background
 * @param drawable
 * @return
 */
public static Bitmap drawableToBitmap(Drawable drawable) {
    // 取 drawable 的长宽
    int w = drawable.getIntrinsicWidth();
    int h = drawable.getIntrinsicHeight();

    // 取 drawable 的颜色格式
    Bitmap.Config config = Bitmap.Config.ARGB_8888;
    // 建立对应 bitmap
    Bitmap bitmap = Bitmap.createBitmap(w, h, config);
    // 建立对应 bitmap 的画布
    Canvas canvas = new Canvas(bitmap);
    // 白色底色   应对透明图
    Paint paint = new Paint();
    paint.setColor(Color.WHITE);
    canvas.drawRect(0, 0, w, h, paint);
    drawable.setBounds(0, 0, w, h);
    // 把 drawable 内容画到画布中
    drawable.draw(canvas);
    return bitmap;
}

/**
 * YUV420sp
 *
 * @param inputWidth
 * @param inputHeight
 * @param scaled
 * @return
 */
public static byte[] getYUV420sp(int inputWidth, int inputHeight,
                                 Bitmap scaled) {
    int[] argb = new int[inputWidth * inputHeight];

    scaled.getPixels(argb, 0, inputWidth, 0, 0, inputWidth, inputHeight);

    byte[] yuv = new byte[inputWidth * inputHeight * 3 / 2];

    encodeYUV420SP(yuv, argb, inputWidth, inputHeight);

    scaled.recycle();

    return yuv;
}

/**
 * RGB转YUV420sp
 *
 * @param yuv420sp
 *            inputWidth * inputHeight * 3 / 2
 * @param argb
 *            inputWidth * inputHeight
 * @param width
 * @param height
 */
private static void encodeYUV420SP(byte[] yuv420sp, int[] argb, int width,
                                   int height) {
    // 帧图片的像素大小
    final int frameSize = width * height;
    // ---YUV数据---
    int Y, U, V;
    // Y的index从0开始
    int yIndex = 0;
    // UV的index从frameSize开始
    int uvIndex = frameSize;

    // ---颜色数据---
    //      int a, R, G, B;
    int R, G, B;
    //
    int argbIndex = 0;
    //

    // ---循环所有像素点,RGB转YUV---
    for (int j = 0; j < height; j++) {
        for (int i = 0; i < width; i++) {

            // a is not used obviously
            // a = (argb[argbIndex] & 0xff000000) >> 24;
            R = (argb[argbIndex] & 0xff0000) >> 16;
            G = (argb[argbIndex] & 0xff00) >> 8;
            B = (argb[argbIndex] & 0xff);
            //
            argbIndex++;

            // well known RGB to YUV algorithm
            Y = ((66 * R + 129 * G + 25 * B + 128) >> 8) + 16;
            U = ((-38 * R - 74 * G + 112 * B + 128) >> 8) + 128;
            V = ((112 * R - 94 * G - 18 * B + 128) >> 8) + 128;

            //
            Y = Math.max(0, Math.min(Y, 255));
            U = Math.max(0, Math.min(U, 255));
            V = Math.max(0, Math.min(V, 255));

            // NV21 has a plane of Y and interleaved planes of VU each
            // sampled by a factor of 2
            // meaning for every 4 Y pixels there are 1 V and 1 U. Note the
            // sampling is every other
            // pixel AND every other scanline.
            // ---Y---
            yuv420sp[yIndex++] = (byte) Y;
            // ---UV---
            if ((j % 2 == 0) && (i % 2 == 0)) {
                //
                yuv420sp[uvIndex++] = (byte) V;
                //
                yuv420sp[uvIndex++] = (byte) U;
            }
        }
    }
}
}


public class QRCodeUtils {
public static String getStringFromQRCode(Drawable drawable) {
    String httpString = null;

    Bitmap bmp = ImageUtils.drawableToBitmap(drawable);
    byte[] data = ImageUtils.getYUV420sp(bmp.getWidth(), bmp.getHeight(), bmp);
    // 处理
    try {
        Hashtable hints = new Hashtable();
        //hints.put(DecodeHintType.CHARACTER_SET, "utf-8");
        hints.put(DecodeHintType.TRY_HARDER, Boolean.TRUE);
        hints.put(DecodeHintType.POSSIBLE_FORMATS, BarcodeFormat.QR_CODE);
        PlanarYUVLuminanceSource source = new PlanarYUVLuminanceSource(data,
                bmp.getWidth(),
                bmp.getHeight(),
                0, 0,
                bmp.getWidth(),
                bmp.getHeight(),
                false);
        BinaryBitmap bitmap1 = new BinaryBitmap(new HybridBinarizer(source));
        QRCodeReader reader2= new QRCodeReader();
        Result result = reader2.decode(bitmap1, hints);

        httpString = result.getText();
    } catch (Exception e) {
        e.printStackTrace();
    }

    bmp.recycle();
    bmp = null;

    return httpString;
}
public static String getStringFromQRCode(Bitmap bmp) {
    String httpString = null;
    byte[] data = ImageUtils.getYUV420sp(bmp.getWidth(), bmp.getHeight(), bmp);
    // 处理
    try {
        Hashtable hints = new Hashtable();
        //hints.put(DecodeHintType.CHARACTER_SET, "utf-8");
        hints.put(DecodeHintType.TRY_HARDER, Boolean.TRUE);
        hints.put(DecodeHintType.POSSIBLE_FORMATS, BarcodeFormat.QR_CODE);
        PlanarYUVLuminanceSource source = new PlanarYUVLuminanceSource(data,
                bmp.getWidth(),
                bmp.getHeight(),
                0, 0,
                bmp.getWidth(),
                bmp.getHeight(),
                false);
        BinaryBitmap bitmap1 = new BinaryBitmap(new HybridBinarizer(source));
        QRCodeReader reader2= new QRCodeReader();
        Result result = reader2.decode(bitmap1, hints);

        httpString = result.getText();
    } catch (Exception e) {
        e.printStackTrace();
    }

    bmp.recycle();
    bmp = null;

    return httpString;
}
}

暂时就先这样吧。还可能做 生成二维码 的功能。

你可能感兴趣的:(Zxing,Android)