解决Zxing解析本地图片二维码,识别率低,识别不出来的问题!
(又做了一些优化,就是在原来的基础上添加上了zbar识别二维码的功能,就是先对图片进行处理,然后通过zxing识别,如果zxing识别失败,再通过zbar识别 20170329)
最近项目里让添加本地图片扫描二维码的功能,本来已经加了扫一扫的功能,产品非得让加上本地图片扫码功能,我看了下搜狐和优酷,他们都是只有扫一扫,没有本地图片扫码,我就想着,产品让加就加吧。
在网上搜了搜,很快就搜到了一个demo,也很快就加到我的项目中了,截取了一张二维码的图片,识别出来了,OK,功能加好了,真开心。后来测试一测,说二维码功能没有添加,我就和他们理论,让他们过来复现,结果真的是识别不出来二维码,到底是啥原因啊,我就开始思考,因为他们是用手机拍得一张二维码图片,二维码在整个图片中占的比例很小,我那天自己测的时候,是整张图片基本上被二维码占完了,所以能扫描成功,接着就是解决问题。
一开始上网搜,zxing二维码本地图片识别不出来,识别率低,搜了半天搜出来一个把图片放大,比如放大一倍,这样就可以识别出来了,下面我把把图片放大的代码贴出来,
Bitmap scanBitmap;
int sampleSize=(int)(options.outHeight/(float)200); options.inJustDecodeBounds=false; if(sampleSize<=0){ options.inSampleSize=1; scanBitmap=BitmapFactory.decodeFile(path, options); Matrix matrix=new Matrix(); matrix.postScale(1.5f,1.5f); scanBitmap=Bitmap.createBitmap(scanBitmap,0,0,scanBitmap.getWidth(),scanBitmap.getHeight(),matrix,true); }else{ options.inSampleSize=sampleSize; scanBitmap=BitmapFactory.decodeFile(path,options); }
然而并没什么用,不仅没什么用,由于把图片放大了,还可能会造成outofmemory,然后就接着搜索,有人说用zbar,说它的图片二维码的识别率比zxing得高,我实在不想改,不过也没办法,就用zbar试了下,然而并没有什么用,这个时候,有点小崩溃,下班后回到家,就一直想到底是为什么呢,ios的就能识别出来,他们用的是他们系统自带的api来做的,难道是他们ios的扫一扫的apI里的算法比zxing和zbar的效率性能要好,肯定的了,不然为什么同样的图片他们的就能识别出二维码呢(猜得),接着继续想办法,然后就是回忆一下,自己手上的其他项目里有没有这些类似的功能参考下,想了一遍,也没有,但是有从相册中获取图片然后截取图片的功能,然后就又有思路了,对了,图片上的二维码识别不出,是因为二维码在整张图片中的占的比例太小,我能不能对这整张图片进行一下裁剪,把没用的多余的图片部分裁剪掉,接着就开始干,下面是对相册图片裁剪的代码:
public class ImageCropActivity extends BaseActivity {private static final int DEFAULT_ASPECT_RATIO_VALUES = 10;private CropImageView cropImageView;private String pre_path; private boolean pre_flag; private int screen_width, screen_height;private TextView tv_ok, tv_canle;private int x;private int y;private TextView tv_crop;private RelativeLayout rl_layout;@Override protected void onCreate(Bundle savedInstanceState) {// TODO Auto-generated method stub super.onCreate(savedInstanceState);requestWindowFeature(Window.FEATURE_NO_TITLE);setContentView(R.layout.activity_image_crop);tv_ok = (TextView) findViewById(R.id.tv_ok);tv_canle = (TextView) findViewById(R.id.tv_canle);tv_ok.setOnClickListener(new OnClickListener() {@Override public void onClick(View v) {// TODO Auto-generated method stub gotoNextStep();}});tv_canle.setOnClickListener(new OnClickListener() {@Override public void onClick(View v) {finish();}});rl_layout = (RelativeLayout) findViewById(R.id.rl_image);tv_crop = (TextView) findViewById(R.id.tv_crop);tv_crop.setOnClickListener(new OnClickListener() {@Override public void onClick(View v) {int switchsize = switchsize();switch (switchsize) {case 0:x = y = 1;break;case 1:x = 4;y = 3;break;case 2:x = 3;y = 4;break;case 3:x = 674;y = 250;break;default:break;}cropImageView.setAspectRatio(x, y);tv_crop.setText(x + ":" + y);}});DisplayMetrics dm = new DisplayMetrics();getWindowManager().getDefaultDisplay().getMetrics(dm);screen_width = dm.widthPixels;screen_height = dm.heightPixels;cropImageView = (CropImageView) findViewById(R.id.CropImageView); Intent preIntent = this.getIntent();pre_path = preIntent.getStringExtra("path");pre_flag = preIntent.getBooleanExtra("flag", true);Bitmap bitmap = null;if (pre_path != null) {bitmap = BitmapUtil.getBitmapFromSDCard(pre_path);} else {bitmap = BitmapUtil.temp; }if (bitmap != null) {bitmap = resizeSurfaceWithScreen(bitmap, screen_width, screen_height);int degree = readPictureDegree(pre_path);bitmap = rotaingImageView(degree, bitmap);cropImageView.setImageBitmap(bitmap);}if (pre_flag) {cropImageView.setAspectRatio(DEFAULT_ASPECT_RATIO_VALUES, DEFAULT_ASPECT_RATIO_VALUES);} else {cropImageView.setAspectRatio(1, 1); rl_layout.setVisibility(View.INVISIBLE);}} private int size_index = 0;public int switchsize() {size_index++;if (size_index >= 3) {size_index = 0;}return size_index; } private Bitmap resizeSurfaceWithScreen(Bitmap bitmap, int screen_width, int screen_height) {int width = bitmap.getWidth();int height = bitmap.getHeight(); if (width < screen_width && height < screen_height) {float scale_width = screen_width * 1.0f / width;float scale_height = screen_height * 1.0f / height;float scale = scale_width > scale_height ? scale_height : scale_width; width *= scale;height *= scale;} else { if (width > screen_width) {height = height * screen_width / width;width = screen_width;}if (height > screen_height) {width = width * screen_height / height;height = screen_height;}}bitmap = Bitmap.createScaledBitmap(bitmap, width, height, false);bitmap = BitmapUtil.zoomBitmap(bitmap, width, height);ByteArrayOutputStream baos = new ByteArrayOutputStream();bitmap.compress(Bitmap.CompressFormat.JPEG, 80, baos);while (baos.toByteArray().length > 1024 * 1024) {baos.reset();bitmap.compress(Bitmap.CompressFormat.JPEG, 50, baos);}ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());Bitmap bitmap_new = BitmapFactory.decodeStream(isBm, null, null);return bitmap_new;}public String saveBitmap(Bitmap bm) {Long tolong = System.currentTimeMillis() / 1000;File f = new File(FileDownloadUtil.getDefaultLocalDir("/cntvScan/temp/"), tolong.toString());if (f.exists()) {f.delete();}try {FileOutputStream out = new FileOutputStream(f);bm.compress(Bitmap.CompressFormat.JPEG, 80, out);ByteArrayOutputStream baos = new ByteArrayOutputStream();while (baos.toByteArray().length > 1024 * 1024) {baos.reset();bm.compress(Bitmap.CompressFormat.JPEG, 50, out);}out.flush();out.close();} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}return f.getAbsolutePath(); }public void gotoNextStep() {try {Bitmap croppedImage = cropImageView.getCroppedImage();ByteArrayOutputStream baos = new ByteArrayOutputStream();croppedImage.compress(Bitmap.CompressFormat.JPEG, 80, baos);byte[] bitmapByte = baos.toByteArray();int width = croppedImage.getWidth();int heigth = croppedImage.getHeight();Intent data = new Intent();data.putExtra("bitmap", bitmapByte);data.putExtra("path", saveBitmap(croppedImage));data.putExtra("width", width);data.putExtra("heigth", heigth);setResult(20, data);finish();} catch (Exception e) {e.printStackTrace();}}/** * * @param angle * @param bitmap * @return Bitmap */ public Bitmap rotaingImageView(int angle, Bitmap bitmap) { Matrix matrix = new Matrix();matrix.postRotate(angle);System.out.println("angle2=" + angle); Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);return resizedBitmap; }public int readPictureDegree(String path) {int degree = 0;try {ExifInterface exifInterface = new ExifInterface(path);int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);switch (orientation) {case ExifInterface.ORIENTATION_ROTATE_90:degree = 90;break;case ExifInterface.ORIENTATION_ROTATE_180:degree = 180;break;case ExifInterface.ORIENTATION_ROTATE_270:degree = 270;break;}} catch (IOException e) {e.printStackTrace();}return degree; } }
还有一些其他的工具类,比较多,我就不贴出来了,终于即使图片上二维码的占的比例比较低的图片,也能识别出来二维码了,如果不做这些处理,是识别不出来的,需要demo的人可以联系我,我给发过去,接下来贴出来几张效果图,这图片放的位置不好看哈!
demo下载地址:https://github.com/guoliuya/scant,花了一上午时间抽出来的!
解决Zxing解析本地图片二维码,识别率低,识别不出来的问题!相关推荐
- 使用zxing 解析图片中的二维码
前言 扫描上传图片中的二维码进行内容解析 提示:以下是本篇文章正文内容,下面案例可供参考 使用步骤 1.先在本地创建文件夹存储图片 代码如下(示例): String path = request.ge ...
- Zxing与 Zbar生成二维码最简单的实现方式
Zxing与 Zbar生成二维码最简单的实现方式 导入依赖 implementation 'cn.bingoogolapple:bga-qrcode-zbar:1.2.1' 或者 implementa ...
- Android实现二维码扫描功能(四)-ZXing识别图片二维码,相册选图
简介 上一篇 Android实现二维码扫描功能(三)-闪光灯控制介绍了光线较弱情况下开启闪光灯来辅助二维码识别的方法. 本篇我们介绍如何识别相册中的图片(含二维码) 动态演示 使用模拟器录制了动画演示 ...
- Android实现二维码扫描功能-ZXing识别图片二维码,相册选图
文章目录 1.演示 2.权限问题 3.实现步骤 4.工具类 5.图片Uri处理(重要更新) 1.演示 2.权限问题 部分朋友在打开相册时遇到读写权限未授权的问题,我在开发的时候没有遇到,也没有注册读写 ...
- 基于ZXing Android实现生成二维码图片和相机扫描二维码图片即时解码的功能
NextQRCode ZXing开源库的精简版 **基于ZXing Android实现生成二维码图片和相机扫描二维码图片即时解码的功能 原文博客 附源码下载地址** 与原ZXingMini项目对比 N ...
- VS2010中使用zxing识别图片二维码
在PC端识别图片二维码有ZXing和OpenCV等方式,Opencv4.0也已经在逐步实现和完善这类的功能.在实际项目工程中,通过使用ZXing编译的库文件,在VC2010中的使用MFC框架实现,动态 ...
- java关于Zxing 生成带Logo 二维码图片失真问题
java关于Zxing 生成带Logo 二维码图片失真问题 问题点 logo本身是高清图片,但是Zxing生成的二维码中,logo像素失真,感觉被严重压缩一样. 排查问题 是Graphics2D 绘制 ...
- 用ZXing 生成条形码和二维码图片
关于ZXing 就不用多介绍了,本问主要介绍如何使用ZXing 生成条形码和二维码的图片. Release 版本的dll下载地址:http://zxingnet.codeplex.com/ 下载完成后 ...
- 前端js解析识别图片二维码
<!--* author:wenqd* email:309820722@qq.com* date:2019-09-18 09:34 --> <!DOCTYPE html> &l ...
最新文章
- 关于const 修饰的一些知识
- Boost:测试bind <void>
- Ext.Net学习笔记10:Ext.Net ComboBox用法
- Java中,与;||与|的区别
- eclipse下的webservice开发
- 从零开始搭建框架SSM+Redis+Mysql(一)之摘要
- python3清屏命令_python3.4中清屏的处理方法
- 黑客帝国代码雨(bat)
- 打印机显示服务器脱机是什么原因,打印机显示“脱机”的原因和解决办法
- 自定义Google搜索引擎
- C语言程序设计————学习知识归纳总结(三)
- matlab实现调整图片的饱和度
- 外企就很舒服?聊聊我在外企的工作体验
- markdown语法高级篇
- 利用开源工具搭一套汉英翻译系统(一):预处理工具
- 安全基础--22--安全测试
- IDEA版最新SMM整合,根据手机号实现登录/注册/修改密码
- c# 两个数组拼接_C#对多个集合和数组的操作方法(合并,去重,判断)
- WebService-CXF
- doxygen教程-5-编写注释
热门文章
- EtherCAT 寻址模式详解
- 银行管理系统 - 2022计科实训QT课设
- 什么是嵌入式?嵌入式开发怎么学
- ARM微控制器与嵌入式系统
- 软件开发获取客户需求的十大沟通技巧
- html图片重叠鼠标点击更换,html实现点击预览图切换图片方法
- 语法解析错误: syntax error, unexpected ‘��‘ (T_STRING), expecting ‘,‘ or ‘;‘
- 事件冒泡详解及阻止事件冒泡
- rand()和srand()函数的用法
- 华为云数据库-RDS for MySQL数据库