Android 玩Google开源库——ZXing二维码、条形码的探索

导语

自从微信、支付宝推出扫一扫功能后,条形码、二维码的使用场景越来越丰富,扫码使用场景:
  • 信息获取(名片、地图、WIFI密码、资料)
  • 网站跳转(跳转到微博、手机网站、网站)
  • 广告推送(用户扫码,直接浏览商家推送的视频、音频广告)
  • 手机电商(用户扫码、手机直接购物下单)
  • 防伪溯源(用户扫码、即可查看生产地;同时可以获取最终消费地)
  • 优惠促销(用户扫码,下载电子优惠券,抽奖)
  • 会员管理(用户手机上获取电子会员信息、VIP服务)
  • 手机支付(扫描商品二维码,通过银行或第三方支付提供的手机端通道完成支付
  • 登陆管理(不需输入账户,密码,扫码登陆)
时代的脚步下,今天我们出行、骑行、购物,去商场和店铺都是支付扫码了。所以我们赶快一起学习一下吧!

一、ZXing简介

ZXing(Zebra Crossing)是Google开源的用于生成和解析多种格式1D/2D条形码的JAVA类库。

jar包下载: http://download.csdn.net/download/csdn_aiyang/10190680

官网地址: http://code.google.com/p/zxing/

GitHub地址: ZXing-GitHub项目地址



二、ZXing方法类源码

BarcodeFormat:条形码格式类

package com.google.zxing;
public enum BarcodeFormat {
    AZTEC,
    CODABAR,// 可表示数字0 - 9,字符$、+、 -、还有只能用作起始/终止符的a,b,c d四个字符,可变长度,没有校验位
    CODE_39,
    CODE_93,
    CODE_128,// 条形码,表示高密度数据, 字符串可变长,符号内含校验码
    DATA_MATRIX,
    EAN_8,
    EAN_13,// 条形码,13位纯数字
    ITF,
    MAXICODE,
    PDF_417,// 二维码
    QR_CODE,// 二维码
    RSS_14,
    RSS_EXPANDED,
    UPC_A,// 统一产品代码A:12位数字,最后一位为校验位
    UPC_E,// 统一产品代码E:7位数字,最后一位为校验位
    UPC_EAN_EXTENSION;
    private BarcodeFormat() {
    }
}

EncodeHintType:编码显示风格

package com.google.zxing;
public enum EncodeHintType {
    ERROR_CORRECTION,//错误修正
    CHARACTER_SET,//编码格式
    MARGIN,//外边距
    PDF417_COMPACT,
    PDF417_COMPACTION,
    PDF417_DIMENSIONS;
    private EncodeHintType() {
    }
}

三、ZXing使用实战小案例

生成二维码

private void initialLayout() {  
    ImageView imageQRCode = (ImageView) findViewById(R.id.imageQRCode);  
    String contentQRCode = "二维码字符串";  
    try {  
        // 根据字符串生成二维码图片并显示在界面上,第二个参数为图片的大小(310*310)  
        Bitmap bitmapQRCode = createQRCode(contentQRCode, 310);  
        imageQRCode.setImageBitmap(bitmapQRCode);  
    } catch (WriterException e) {  
        e.printStackTrace();  
    }  
}  
 private static final int BLACK = 0xff000000; //二维码颜色 
  
 public static Bitmap createQRCode(String str, int widthAndHeight)  
            throws WriterException {  
        Hashtable hints = new Hashtable();  
        hints.put(EncodeHintType.CHARACTER_SET, "utf-8");  
        BitMatrix matrix = new MultiFormatWriter().encode(str,  
                BarcodeFormat.QR_CODE, widthAndHeight, widthAndHeight);  
        int width = matrix.getWidth();  
        int height = matrix.getHeight();  
        int[] pixels = new int[width * height];  
  
        for (int y = 0; y < height; y++) {  
            for (int x = 0; x < width; x++) {  
                if (matrix.get(x, y)) {  
                    pixels[y * width + x] = BLACK;  
                }  
            }  
        }  
        Bitmap bitmap = Bitmap.createBitmap(width, height,  
                Bitmap.Config.ARGB_8888);  
        bitmap.setPixels(pixels, 0, width, 0, 0, width, height);  
        return bitmap;  
    }  

Android 玩Google开源库——ZXing二维码、条形码的探索_第1张图片

二维码 · 功能升级!
如果想在中心放上小图标,如图效果:
Android 玩Google开源库——ZXing二维码、条形码的探索_第2张图片  (在带入zxing.jar后,代码可直接复制到项目中使用。)
/**
     * 生成二维码图片
     *
     * @param codeUrl
     * @param icon
     */
    private void showQREncode(String codeUrl, Bitmap icon) {
        if (null != codeUrl && !codeUrl.equals("")) 
            try {
                Bitmap bitmap = createBitmap(new String(codeUrl.getBytes(), "UTF-8"), icon);
                mQrcodeImg.setImageBitmap(bitmap);
                mQRCodeShow = true;
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else {
            CommonTools.showShortToast(mContext, "请输入二维码信息!");
        }
    }
    /**
     * 生成二维码 中间插入小图片
     */
    private Bitmap createBitmap(String str, Bitmap icon) throws WriterException {
        icon = zoomBitmap(icon, IMAGE_HALFWIDTH);
        Hashtable hints = new Hashtable();
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
        hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
        hints.put(EncodeHintType.MARGIN, 1);
        // 生成二维矩阵,编码时指定大小,不要生成了图片以后再进行缩放,这样会模糊导致识别失败
        BitMatrix matrix = new MultiFormatWriter().encode(str, BarcodeFormat.QR_CODE, 380, 380, hints);
        int width = matrix.getWidth();
        int height = matrix.getHeight();
        // 二维矩阵转为一维像素数组,也就是一直横着排了
        int halfW = width / 2;
        int halfH = height / 2;
        int[] pixels = new int[width * height];
        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
                if (x > halfW - IMAGE_HALFWIDTH && x < halfW + IMAGE_HALFWIDTH && y > halfH - IMAGE_HALFWIDTH && y < halfH + IMAGE_HALFWIDTH) {
                    pixels[y * width + x] = icon.getPixel(x - halfW + IMAGE_HALFWIDTH, y - halfH + IMAGE_HALFWIDTH);
                } else {
                    if (matrix.get(x, y)) {
                        pixels[y * width + x] = 0xff000000;
                    } else { // 无信息设置像素点为白色
                        pixels[y * width + x] = 0xffffffff;
                    }
                }
            }
        }
        Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        // 通过像素数组生成bitmap
        bitmap.setPixels(pixels, 0, width, 0, 0, width, height);

        return bitmap;
    }
    /**
     * 缩放图片
     */
    private Bitmap zoomBitmap(Bitmap icon, int h) {
        // 缩放图片
        Matrix m = new Matrix();
        float sx = (float) 2 * h / icon.getWidth();
        float sy = (float) 2 * h / icon.getHeight();
        m.setScale(sx, sy);
        // 重新构造一个图片
        return Bitmap.createBitmap(icon, 0, 0, icon.getWidth(), icon.getHeight(), m, false);
    }

生成条形码

 /**
     * 转换条形码
     *
     * @param str 条形码的字符串
     * @return
     * @throws WriterException
     */
    private Bitmap BarcodeFormatCode(String str) {
        int width = 800;
        int height = 160;
        BarcodeFormat barcodeFormat = BarcodeFormat.CODE_128;
        BitMatrix matrix = null;
        try {
            matrix = new MultiFormatWriter().encode(str, barcodeFormat, width, height, null);
            return bitMatrix2Bitmap(matrix);
        } catch (WriterException e) {
            e.printStackTrace();
        }
        return null;
    }

    private Bitmap bitMatrix2Bitmap(BitMatrix matrix) {
        int w = matrix.getWidth();
        int h = matrix.getHeight();
        int[] rawData = new int[w * h];
        for (int i = 0; i < w; i++) {
            for (int j = 0; j < h; j++) {
                int color = Color.WHITE;
                if (matrix.get(i, j)) {
                    // 有内容的部分,颜色设置为黑色,可以自己修改成其他颜色
                    color = Color.BLACK;
                }
                rawData[i + (j * w)] = color;
            }
        }

        Bitmap bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
        bitmap.setPixels(rawData, 0, w, 0, 0, w, h);
        return bitmap;
    }

Android 玩Google开源库——ZXing二维码、条形码的探索_第3张图片

扫码解析

zxing.CaptureActivity中handleDecode处理解析好的数据即可
/** 
 * A valid barcode has been found, so give an indication of success and show 
 * the results. 
 * 
 * @param rawResult   The contents of the barcode. 
 * @param scaleFactor amount by which thumbnail was scaled 
 * @param barcode     A greyscale bitmap of the camera data which was decoded. 
 */  
public void handleDecode(final Result rawResult, Bitmap barcode,  
                         float scaleFactor) {  
    inactivityTimer.onActivity();  
    boolean fromLiveScan = barcode != null;  
  
    if (fromLiveScan) {  
        beepManager.playBeepSoundAndVibrate();  
    }  
  
    finish();  
    String scanResult = rawResult.getText();  
    if (null != scanResult && scanResult.trim().length() > 0) {  
        Intent intentBind = new Intent(CaptureActivity.this,  
                BindActivity.class);  
        intentBind.putExtra("physicalId", scanResult);  
        startActivity(intentBind);  
    }  
  
    switch (source) {  
        case NATIVE_APP_INTENT:  
        case PRODUCT_SEARCH_LINK:  
            break;  
  
        case ZXING_LINK:  
            break;  
  
        case NONE:  
            break;  
    }  
}  



你可能感兴趣的:(Android 玩Google开源库——ZXing二维码、条形码的探索)