转载请注明出处
作者:AboutJoke ( http://blog.csdn.net/u013200308 )
原文链接:http://blog.csdn.net/u013200308/article/details/68067564

最近在项目中需要实现对二维码的识别,所以第一时间就想到了zxing,期间各种编译,然后又从网上找了很多的文章终于把需要的功能实现了出来,下面就和大家分享一下。


拍照识别

总体来说,拍照识别还是比较容易的。我们设置好需要修改的参数后,然后调用zxing的CaptureActivity就可以打开拍照识别的页面,识别完成后,结果会在onActivityResult中返回,在这里我们就可以对结果进行处理了。

打开拍照页面

private void callCapture(String characterSet) {/*** 获取屏幕的宽度,并将宽度的2/3作为扫码区宽度*/int width = wm.getDefaultDisplay().getWidth() * 2 / 3;Intent intent = new Intent();intent.setAction(Intents.Scan.ACTION);intent.putExtra(Intents.Scan.MODE, Intents.Scan.QR_CODE_MODE);intent.putExtra(Intents.Scan.CHARACTER_SET, characterSet);/*** WIDTH==HEIGHT 设置方形扫码取景区* 取景区的总宽度是屏幕宽度的2/3——适配所有机型* */intent.putExtra(Intents.Scan.WIDTH, width);intent.putExtra(Intents.Scan.HEIGHT, width);//intent.setClass(this, CaptureActivity.class);//进入zxing模块中的CaptureActivitystartActivityForResult(intent, CAMERA_OK);}

获取扫描到的结果

String result = data.getStringExtra(Intents.Scan.RESULT);
String recode = recode(result);

从相册选取图片识别

从相册选取图片识别,处理步骤会比拍照识别稍微复杂一点。在这里我们有两种方法可以使用,具体的选择就看你了。具体的逻辑为

  • 从相册选取图片
  • 根据图片路径生成bitmap并进行解析
  • 处理解析结果防止乱码

下面我们就按照上面逻辑来一步步的实现:

从相册选取图片

private void photo() {// 激活系统图库,选择一张图片Intent innerIntent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);Intent wrapperIntent = Intent.createChooser(innerIntent, "选择二维码图片");startActivityForResult(wrapperIntent, REQUEST_CODE);}

在onActivityResult中获取选中图片的路径

                    String[] proj = {MediaStore.Images.Media.DATA};// 获取选中图片的路径Cursor cursor = this.getContentResolver().query(data.getData(),proj, null, null, null);if (cursor.moveToFirst()) {int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);photo_path = cursor.getString(column_index);if (photo_path == null) {photo_path = getPath(this,data.getData());}}cursor.close();

根据图片路径生成bitmap并进行解析

在这里我们需要拿到选择图片的路径,然后生成一张bitmap。

构建bitmap
       if (TextUtils.isEmpty(path)) {return null;}// DecodeHintType 和EncodeHintTypeHashtable<DecodeHintType, String> hints = new Hashtable<DecodeHintType, String>();hints.put(DecodeHintType.CHARACTER_SET, "utf-8"); // 设置二维码内容的编码BitmapFactory.Options options = new BitmapFactory.Options();options.inJustDecodeBounds = true; // 先获取原大小scanBitmap = BitmapFactory.decodeFile(path, options);options.inJustDecodeBounds = false; // 获取新的大小int sampleSize = (int) (options.outHeight / (float) 200);if (sampleSize <= 0)sampleSize = 1;options.inSampleSize = sampleSize;scanBitmap = BitmapFactory.decodeFile(path, options);

有了bitmap后,我们可以选取两种不同的解析方式来解析图片。

将bitmap转为yuv解析
        LuminanceSource source1 = new PlanarYUVLuminanceSource(rgb2YUV(scanBitmap), scanBitmap.getWidth(),scanBitmap.getHeight(), 0, 0, scanBitmap.getWidth(),scanBitmap.getHeight());BinaryBitmap binaryBitmap = new BinaryBitmap(new HybridBinarizer(source1));MultiFormatReader reader1 = new MultiFormatReader();Result result1;try {result1 = reader1.decode(binaryBitmap);String content = result1.getText();Log.e("123content", content);} catch (NotFoundException e1) {e1.printStackTrace();}
将bitmap转为rgb解析
        RGBLuminanceSource source = new RGBLuminanceSource(scanBitmap);BinaryBitmap bitmap1 = new BinaryBitmap(new HybridBinarizer(source));QRCodeReader reader = new QRCodeReader();try {return reader.decode(bitmap1, hints);} catch (NotFoundException | ChecksumException | FormatException e) {e.printStackTrace();}

大部分二维码的识别都是基于二值化的方法,在色域的处理上,YUV的二值化效果要优于RGB,并且RGB图像在处理中不支持旋转。因此,一种优化的思路是将所有ARGB编码的图像转换成YUV编码,再使用PlanarYUVLuminanceSource去处理生成的结果,所以个人是比较推荐第一种解析方法的,这里还需要一个rgb2YUV的方法。

public byte[] rgb2YUV(Bitmap bitmap) {int width = bitmap.getWidth();int height = bitmap.getHeight();int[] pixels = new int[width * height];bitmap.getPixels(pixels, 0, width, 0, 0, width, height);int len = width * height;byte[] yuv = new byte[len * 3 / 2];int y, u, v;for (int i = 0; i < height; i++) {for (int j = 0; j < width; j++) {int rgb = pixels[i * width + j] & 0x00FFFFFF;int r = rgb & 0xFF;int g = (rgb >> 8) & 0xFF;int b = (rgb >> 16) & 0xFF;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 = y < 16 ? 16 : (y > 255 ? 255 : y);u = u < 0 ? 0 : (u > 255 ? 255 : u);v = v < 0 ? 0 : (v > 255 ? 255 : v);yuv[i * width + j] = (byte) y;
//                yuv[len + (i >> 1) * width + (j & ~1) + 0] = (byte) u;
//                yuv[len + (i >> 1) * width + (j & ~1) + 1] = (byte) v;}}return yuv;}

处理解析结果

其实在上一步的时候我们已经得到了扫描的结果,但我们还需要对结果进行一下编码处理,以防止最后显示的结果乱码

 private String recode(String str) {String format = "";try {boolean ISO = Charset.forName("ISO-8859-1").newEncoder().canEncode(str);if (ISO) {format = new String(str.getBytes("ISO-8859-1"), "GB2312");Log.i("1234      ISO8859-1", format);} else {format = str;Log.i("1234      stringExtra", str);}} catch (UnsupportedEncodingException e) {e.printStackTrace();}return format;}

到这里我们的二维码识别功能就已经实现了,具体的效果呢大家可以下载源码去体验一下,识别速度还是很快的。

自定义内容

如果你对二维码的拍照页面不是很满意的话,可以去ViewfinderView类中修改页面,里面有注释可以很容易的读懂。如果你下载了我的demo体验的话你会发现拍照识别成功是有声音提示的,这个功能的实现在BeepManager中,还可以选择识别成功后是否震动,具体的可以通过阅读代码去修改。

下来有时间我会在集成一个类似微信,检测到环境较为黑暗的时候提示是否打开闪光灯的功能,扫下面的二维码下载demo去体验吧。

使用Zxing实现拍照,选取图片识别二维码相关推荐

  1. Android利用zxing用相机扫描识别二维码(添加闪光灯和本地二维码)超详细教程

    之前写了怎么用zxing的jar包进行简单的识别和生成二维码,以及生成带图片的二维码. 接下来单独说说怎么用相机扫描二维码,用相机扫描二维码相对于前面的生成二维码,识别二维码来说要麻烦一点,网上的教程 ...

  2. Android利用zxing生成二维码,识别二维码,中间填充图片超详细、超简易教程

    gayhub上的zxing可用于生成二维码,识别二维码 gayhub地址:https://github.com/zxing/zxing 此文只是简易教程,文末附有完整代码和demo下载地址,进入正题: ...

  3. python二维码生成识别代码_Python3+qrcode+zxing生成和识别二维码教程

    一.安装依赖库 pip install qrcode pillow image zxing pillow是python3中PIL的代替库,image是生成图版需要用到的库 安装image时报错&quo ...

  4. java识别二维码-zxing

    1.pom文件中引入 <dependency><groupId>com.google.zxing</groupId><artifactId>javase ...

  5. USB摄像头预览识别二维码

    博客: 安卓之家 掘金: jp1017 微博: 追风917 CSDN: 蒋朋的家 简书: 追风917 前言 二维码现在用的超级多,其实它就是一种编码,把字符串编码保存成一个图片,我们扫描图片得到字符串 ...

  6. WinForm调用摄像头扫码识别二维码

    前言 因公司业务需求,需要在Windows系统下调用摄像头识别二维码需求,就有了这个功能.根据网上网友提供的一些资料,自己整合应用到项目中,效果还不错(就是感觉像素不是太好).现在将调用摄像头+识别二 ...

  7. SNF开发平台WinForm-平板拍照及扫描二维码功能

    在我们做项目的时候,经常会有移动平板处理检验,审核等,方便移动办公.这时就需要在现场拍照上传问题,把当场问题进行上传,也有已经拍完照的图片或加工过的图片进行上传.还有在车间现场一体机,工控机 这种产物 ...

  8. HTML5实现扫描识别二维码/生成二维码

    扫描识别二维码 思路: 1. 操作摄像头,获取图片.HTML5 WEBRTC的navigator.getUserMedia方法去实时获取摄像头资源.  2. 利用canvas使用相关算法分析图片识别图 ...

  9. Zing实现本地相册识别二维码

    前言 最近公司的项目需要加入本地相册识别二维码的功能,就类似与微信那样.大家都知道二维码识别目前火的一个是Zing,一个就是Zbar,针对于这两个的区别,在此也不再赘述.(PS:网上的资料有很多)由于 ...

最新文章

  1. 基于平面几何精确且鲁棒的尺度恢复单目视觉里程计
  2. Oracle内部错误ORA-07445:[_memcmp()+88] [SIGSEGV]一例
  3. Android Jetpack组件之 Room使用-源码
  4. python画五角星-python画五角星和六角星程序 | 学步园
  5. Lesson 9.5 从0实现多层神经网络的正向传播
  6. Mybatis:传输多个参数
  7. 浅谈AI视频技术超分辨率
  8. sap.dfa.help.utils.adapters.hm.myadapter
  9. OJ1077: 字符串加密(C语言)
  10. 谷歌地图添加点击事件 Google Maps API V3: Add click event listener to all (multiple) marker
  11. 思维方式是看待事物的角度、方式和方法,它对人的言行起到决定性作用
  12. python代码翻译器-用python实现百度翻译的示例代码
  13. 蝌蚪网课助手mac_疫情期间如何录网课?(干货教程)手把手教你录出高质量网课。...
  14. [Egret学习笔记 二]MovieClip的使用
  15. mysql编程界面_MySQL图形界面客户端
  16. 2021-02-23
  17. 尚硅谷 clickHouse
  18. BERT代码的解读1---数据处理部分
  19. 猜字母 把abcd...s共19个字母组成的序列重复拼接106次,得到长度为2014的串。
  20. react 改变css样式_react怎么更改css样式

热门文章

  1. redo日志的刷盘策略
  2. 天龙八部技术分析报告
  3. vue使用高德地图实现多种点样式海量点渲染及信息显示
  4. 2023济南科创金融论坛 郭为主旨演讲:数字化的力量
  5. 浅谈个人对职业发展的一点思考
  6. hdfs 目录设置配额 、查询配额使用情况 、清除配额
  7. 【常见网吧计算机系统故障及其解决方法】
  8. 基于C语言中野指针的深入解析
  9. Fallen Art 堕落的艺术
  10. 达梦数据库通过dmp文件导入数据