博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Zxing库
阅读量:4691 次
发布时间:2019-06-09

本文共 6393 字,大约阅读时间需要 21 分钟。

一.介绍

  Zxing是一个开放的源码,用java实现的多种样式的1D/2D条码处理库,它包含了联系到其他语言的端口。Zxing可以实现手机的内置摄像头完成条码的扫描及解码。目前支持:UPC-A ,UPC-E ,EAN-8 ,EAN-13 ,39 码,93码。

二.Zxing库的主要类

  1.CaptureActivity :启动Activity,也就是扫描器

  2.CaptureActivityHandler :解码处理器,负责调用另外的线程进行解码

  3.DecodeThread :解码线程

  4.com.google.zxing.client.android.camera包:摄像头调用包

  5.ViewfinderView :自定义的View,就是我们看到的拍摄中间的框框

三. 使用Zxing生成二维码

//Edited by mythou//
  //要转换的地址或字符串,可以是中文    public void createQRImage(String url)    {        try        {            //判断URL合法性            if (url == null || "".equals(url) || url.length() < 1)            {                return;            }            Hashtable
hints = new Hashtable
(); hints.put(EncodeHintType.CHARACTER_SET, "utf-8"); //图像数据转换,使用了矩阵转换 BitMatrix bitMatrix = new QRCodeWriter().encode(url, BarcodeFormat.QR_CODE, QR_WIDTH, QR_HEIGHT, hints); int[] pixels = new int[QR_WIDTH * QR_HEIGHT]; //下面这里按照二维码的算法,逐个生成二维码的图片, //两个for循环是图片横列扫描的结果 for (int y = 0; y < QR_HEIGHT; y++) { for (int x = 0; x < QR_WIDTH; x++) { if (bitMatrix.get(x, y)) { pixels[y * QR_WIDTH + x] = 0xff000000; } else { pixels[y * QR_WIDTH + x] = 0xffffffff; } } } //生成二维码图片的格式,使用ARGB_8888 Bitmap bitmap = Bitmap.createBitmap(QR_WIDTH, QR_HEIGHT, Bitmap.Config.ARGB_8888); bitmap.setPixels(pixels, 0, QR_WIDTH, 0, 0, QR_WIDTH, QR_HEIGHT); //显示到一个ImageView上面 sweepIV.setImageBitmap(bitmap); } catch (WriterException e) { e.printStackTrace(); } }   上面就是二维码生成的方法接口,如果你只是使用者方法,很简单,只要传一个URL即可。或者像现在一些移动的App推广,把App下载地址转成二维码;   上面代码做的事情不多,主要是调用Zxing库里面的QRCodeWriter().encode的方法对我们传进去的URL进行编码 四.扫描二维码获取信息   扫描获取二维码信息工作稍微复杂一点,主要是需要编写的Camera的使用,这个跟我们一般使用的Camera一样,需要使用Sufaceview作为预览;   获取二维码数据的关键在于处理说在Camera的自动对焦回函数那里,调用ZXing的解码接口:
//Edited by mythou//
  private void restartPreviewAndDecode() {    if (state == State.SUCCESS) {      state = State.PREVIEW;      CameraManager.get().requestPreviewFrame(decodeThread.getHandler(), R.id.decode);      CameraManager.get().requestAutoFocus(this, R.id.auto_focus);      activity.drawViewfinder();    }  }
  由于解码需要一点时间,所以ZXing的解码调用,都是使用Handler作为线程通讯机制,解码的工作都是放在独立线程里面使用的,如果你放在主线程解码,恐怕ANR问题是避免不了
public void handleMessage(Message message) {    switch (message.what) {      case R.id.auto_focus:        //Log.d(TAG, "Got auto-focus message");        // When one auto focus pass finishes, start another. This is the closest thing to        // continuous AF. It does seem to hunt a bit, but I'm not sure what else to do.        if (state == State.PREVIEW) {          CameraManager.get().requestAutoFocus(this, R.id.auto_focus);        }        break;      case R.id.restart_preview:        Log.d(TAG, "Got restart preview message");        restartPreviewAndDecode();        break;      case R.id.decode_succeeded:    //解码成功,获取到界面的结果和原来的二维码数据        Log.d(TAG, "Got decode succeeded message");        state = State.SUCCESS;        Bundle bundle = message.getData();        Bitmap barcode = bundle == null ? null :            (Bitmap) bundle.getParcelable(DecodeThread.BARCODE_BITMAP);        activity.handleDecode((Result) message.obj, barcode);        break;      case R.id.decode_failed:        // We're decoding as fast as possible, so when one decode fails, start another.        state = State.PREVIEW;        CameraManager.get().requestPreviewFrame(decodeThread.getHandler(), R.id.decode);        break;      case R.id.return_scan_result:        Log.d(TAG, "Got return scan result message");        activity.setResult(Activity.RESULT_OK, (Intent) message.obj);        activity.finish();        break;      case R.id.launch_product_query:        Log.d(TAG, "Got product query message");        String url = (String) message.obj;        Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);        activity.startActivity(intent);        break;    }  }
 
  上面是解码的线程处理不同状态时候需要注意的地方,我们这里只看获取图像成功的地方,成功获取图片解码的是在DecodeThread里面实现的; DecodeThread里面解码成功后,会把数据序列化,然后保存到Bundle里面,我们可以直接通过Bundle的序列化,获取图片数据; 同时会把解码后的结果保存到MSG里面,然后可以根据实际情况进行处理;例如上面代码,解码成功后,会调用一个处理函数:
 
public void handleMessage(Message message) {    switch (message.what) {      case R.id.auto_focus:        //Log.d(TAG, "Got auto-focus message");        // When one auto focus pass finishes, start another. This is the closest thing to        // continuous AF. It does seem to hunt a bit, but I'm not sure what else to do.        if (state == State.PREVIEW) {          CameraManager.get().requestAutoFocus(this, R.id.auto_focus);        }        break;      case R.id.restart_preview:        Log.d(TAG, "Got restart preview message");        restartPreviewAndDecode();        break;      case R.id.decode_succeeded:    //解码成功,获取到界面的结果和原来的二维码数据        Log.d(TAG, "Got decode succeeded message");        state = State.SUCCESS;        Bundle bundle = message.getData();        Bitmap barcode = bundle == null ? null :            (Bitmap) bundle.getParcelable(DecodeThread.BARCODE_BITMAP);        activity.handleDecode((Result) message.obj, barcode);        break;      case R.id.decode_failed:        // We're decoding as fast as possible, so when one decode fails, start another.        state = State.PREVIEW;        CameraManager.get().requestPreviewFrame(decodeThread.getHandler(), R.id.decode);        break;      case R.id.return_scan_result:        Log.d(TAG, "Got return scan result message");        activity.setResult(Activity.RESULT_OK, (Intent) message.obj);        activity.finish();        break;      case R.id.launch_product_query:        Log.d(TAG, "Got product query message");        String url = (String) message.obj;        Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);        activity.startActivity(intent);        break;    }  }
 
   上面就是整个二维码的解码流程,里面因为涉及很多Camera的使用,所以你如果需要使用二维码识别,需要注意一下你的程序需要申请以下权限,一般的Camera使用以及Camrea的自动对焦等。
五.结尾

ZXing开源项目Google Code地址:

ZXingDemo下载:

 

 
 

转载于:https://www.cnblogs.com/yiweiaimeng/p/4998166.html

你可能感兴趣的文章
取余操作的原理
查看>>
分布式系统理论(二):一致性协议Paxos
查看>>
NHibernate版本不一致问题
查看>>
oracle 误删除数据,回退表数据
查看>>
centos安装中文支持(转)
查看>>
Android Weekly Notes Issue #218
查看>>
Java 日志管理最佳实践
查看>>
poj 1228
查看>>
博客目录 Blog directory
查看>>
码农干货系列【6】--javascript异步编程之:世界上最短的Promise库
查看>>
IO流
查看>>
关于读书
查看>>
list转换为map
查看>>
试用cmd markdown
查看>>
WPF学习之路由事件
查看>>
HDFS 通信接口
查看>>
oracle函数 NLS_INITCAP(x[,y])
查看>>
使用 /proc 文件系统
查看>>
Android Launcher3 开启旋转后有部分任务在旋转后会显示出来
查看>>
团队作业4——第一次项目冲刺(Alpha版本)
查看>>