欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

ZXing二维码、条形码生成和扫描

程序员文章站 2024-01-27 11:38:16
...

1、条形码和二维码的编解码过程可以看->这篇blog。<-
2、由于新项目的需求,需要扫描二维码和条形码,而且有可能是在暗光环境下进行,所以这篇文章加上扫描以及打开闪光灯的功能,网上找了下->这个<-demo比较合乎要求,所以我们下载下来改一改代码。


1、集成ZXing.jar包

ZXing二维码、条形码生成和扫描

ZXing包可以自行百度下载,也可以去我的资源页下载,点这里


2、EncodingUtils–二维码、条形码生成工具类

public class EncodingUtils {
    private static final int BLACK = 0xff000000;

    /**
     * 1、生成二维码
     *
     * @param str
     * @param widthAndHeight
     * @return
     */
    public static Bitmap createQRCode(String str, int widthAndHeight) {
        try {
            // 判断URL合法性
            if (str == null || "".equals(str) || str.length() < 1) {
                return null;
            }
            Hashtable<EncodeHintType, String> hints = new Hashtable<EncodeHintType, String>();
            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循环是图片横列扫描的结果
            for (int y = 0; y < height; y++) {
                for (int x = 0; x < width; x++) {
                    if (matrix.get(x, y)) {
                        pixels[y * width + x] = BLACK;
                    }
                }
            }
            // 生成二维码图片的格式,使用ARGB_8888
            Bitmap bitmap = Bitmap.createBitmap(width, height,
                    Bitmap.Config.ARGB_8888);
            bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
            return bitmap;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }


    /**
     * 2、生成条形码
     *
     * @param context
     * @param contents      需要生成的内容
     * @param desiredWidth  生成条形码的宽带
     * @param desiredHeight 生成条形码的高度
     * @return
     */
    public static Bitmap creatBarcode(Context context, String contents, int desiredWidth, int desiredHeight) {
        try {
            Bitmap ruseltBitmap = null;
            /**
             * 图片两端所保留的空白的宽度
             */
            int marginW = 20;
            /**
             * 条形码的编码类型
             */
            BarcodeFormat barcodeFormat = BarcodeFormat.CODE_128;
            ruseltBitmap = encodeAsBitmap(contents, barcodeFormat,
                    desiredWidth, desiredHeight);
            return ruseltBitmap;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /*以下的为条形码生成辅助工具方法*/

    /**
     * 生成条形码的Bitmap
     *
     * @param contents      需要生成的内容
     * @param format        编码格式
     * @param desiredWidth
     * @param desiredHeight
     * @return
     * @throws WriterException
     */
    protected static Bitmap encodeAsBitmap(String contents, BarcodeFormat format, int desiredWidth, int desiredHeight) {
        final int WHITE = 0xFFFFFFFF;
        final int BLACK = 0xFF000000;

        MultiFormatWriter writer = new MultiFormatWriter();
        BitMatrix result = null;
        try {
            result = writer.encode(contents, format, desiredWidth,
                    desiredHeight, null);
        } catch (WriterException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        int width = result.getWidth();
        int height = result.getHeight();
        int[] pixels = new int[width * height];
        // All are 0, or black, by default
        for (int y = 0; y < height; y++) {
            int offset = y * width;
            for (int x = 0; x < width; x++) {
                pixels[offset + x] = result.get(x, y) ? BLACK : WHITE;
            }
        }

        Bitmap bitmap = Bitmap.createBitmap(width, height,
                Bitmap.Config.ARGB_8888);
        bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
        return bitmap;
    }

}

3、EncodingUtils在代码中的调用

String billNo = "目标字符串";
...
//二维码
Bitmap qrCode = EncodingUtils.createQRCode(billNo, 800);
//条形码
Bitmap barcode = EncodingUtils.creatBarcode(this, billNo, 1000, 500);
...

4、结果显示

ZXing二维码、条形码生成和扫描ZXing二维码、条形码生成和扫描


补上扫描二维码和条形码的代码

开始使用

把作者的->这个<-demo代码down下来,
这个demo包括包括二维码扫描,条形码扫描,二维码生成,条形码生成,从图片中扫描二维码或者条形码,闪光灯控制。
完全符合我们项目中的使用需求,先看下这个demo的功能界面

ZXing二维码、条形码生成和扫描

然后我们看下怎么把这些功能移植到我们的项目中去使用,
1、先把zxing.jar加到项目中
2、复制需要的类文件,包括 defineview 和 zxing包(文件夹)下的代码

ZXing二维码、条形码生成和扫描

MyImageView–画出扫描框的四个脚的脚边框

3、如果不想自己写扫描界面可以把layout文件夹下的布局文件activity_scan_code.xml和项目中的CommonScanActivity.java也复制到自己的项目中,也可以仿照这些代码自己写扫描界面

ZXing二维码、条形码生成和扫描ZXing二维码、条形码生成和扫描

4、使用到图片和选择器,也可以换成自己的
ZXing二维码、条形码生成和扫描

5、raw文件夹及子文件
ZXing二维码、条形码生成和扫描

6、values文件夹下的:Qrcode_ids.xml
ZXing二维码、条形码生成和扫描

7、在colors.xml中加上

<color name="scan_bg">#7f000000</color>

8、在strings.xml中加上

<string name="scan_allcode_hint">将条形码对入取景框,即可自动扫描</string>

9、如果使用作者的扫描界面CommonScanActivity的话就需要把作者的Constant.java也复制过去,另外最重要的是要在清单文件中加上扫描需要的权限!!

ok,到这里资源就导入完毕了,可以开始使用了


生成条形码(一维码)

Bitmap barCode = EncodingHandler.createBarCode(text, 600, 300);

生成二维码

Bitmap barCode = EncodingHandler.create2Code(text, 600);

扫描

条形码DecodeThread.BARCODE_MODE
二维码DecodeThread.QRCODE_MODE
条形码和二维码DecodeThread.ALL_MODE

scanManager = new ScanManager(this, surfaceView, rootView, rlCropView, scanLine, DecodeThread.BARCODE_MODE, new ScanListener() {
        @Override
        public void scanResult(Result rawResult, Bundle bundle) {
            ToastUtil.showShortToast(context, rawResult.getText());
            Intent intent = new Intent();
            intent.putExtra("BarCode", rawResult.getText());
            setResult(2, intent);
            finish();
        }

        @Override
        public void scanError(Exception e) {
            ToastUtil.showShortToast(context, e.getMessage());
        }
    });

作者扫描类CommonScanActivity中的调用

 case  R.id.scan_2code: //扫描二维码
 intent=new Intent(this,CommonScanActivity.class);
 intent.putExtra(Constant.REQUEST_SCAN_MODE,Constant.REQUEST_SCAN_MODE_QRCODE_MODE);
 startActivity(intent);
 break;
 case  R.id.scan_bar_code://扫描条形码
 intent=new Intent(this,CommonScanActivity.class);
 intent.putExtra(Constant.REQUEST_SCAN_MODE,Constant.REQUEST_SCAN_MODE_BARCODE_MODE);
 startActivity(intent);
 break;
 case  R.id.scan_code://扫描条形码或者二维码
 intent=new Intent(this,CommonScanActivity.class);
 intent.putExtra(Constant.REQUEST_SCAN_MODE,Constant.REQUEST_SCAN_MODE_ALL_MODE);
 startActivity(intent);
 break;

扫描集成了,至于扫描之后的逻辑操作就要应项目而异了