Android实现二维码扫描功能(二)-ZXing个性化与近距离识别优化
来源:互联网 发布:java交换两个数 编辑:程序博客网 时间:2024/06/11 06:02
简介
上一篇Android实现二维码扫描功能(一)-ZXing插件接入介绍了ZXing框架接入方法,已经可以初步集成扫码功能到项目中。
本篇我们对扫码界面进行优化,并对ZXing近距离无法识别的问题做出优化。
个性化定制
每个APP都有自己的表现形式,实现个性化扫码界面定制,主要有两个地方:
- activity_scanner.xml界面文件
- com.google.zxing.view.ViewfinderView扫码控件
下面分别来说明。
界面文件
activity_scanner.xml源码如下:
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <include layout="@layout/toolbar_scanner" /> <FrameLayout android:layout_width="match_parent" android:layout_height="match_parent"> <SurfaceView android:id="@+id/scanner_view" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="center" /> <com.google.zxing.view.ViewfinderView android:id="@+id/viewfinder_content" android:layout_width="wrap_content" android:layout_height="wrap_content" app:corner_color="@color/corner_color" app:frame_color="@color/viewfinder_frame" app:label_text="二维码/条形码扫描" app:label_text_color="@color/colorAccent" app:laser_color="@color/laser_color" app:mask_color="@color/viewfinder_mask" app:result_color="@color/result_view" app:result_point_color="@color/result_point_color" /> </FrameLayout></LinearLayout>
界面分析:
- 顶层采用LinearLayout实现自上至下的方向,基本不用修改;
<include layout="@layout/toolbar_scanner" />
引用toolbar布局文件,稍后给出,这里可以加入菜单项目、返回键等;- FrameLayout布局将相机可扫描窗口叠加在一起;
- SurfaceView装载相机内容,即相机拍摄到的画面;
- com.google.zxing.view.ViewfinderView扫码自定义View,主要由遮罩层、四个角的边框、扫描线等组成。
toolbar_scanner.xml,比较简单
<?xml version="1.0" encoding="utf-8"?><android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimary" app:contentInsetStart="0dip"> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center_vertical"> <ImageButton android:id="@+id/btn_back" android:layout_width="40dip" android:layout_height="40dip" android:background="?attr/selectableItemBackground" android:padding="10dip" android:scaleType="centerCrop" android:src="@drawable/btn_back" /> <TextView android:id="@+id/txt_title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:text="扫描二维码" android:textColor="@android:color/white" android:textSize="18sp" /> </RelativeLayout></android.support.v7.widget.Toolbar>
可根据需求调整toolbar内容,这里我们就不多说。
扫码控件定制
现行使用的ViewfinderView已经是经过前辈修改过的版本,他们加入了边框和扫描线,基于这个版本我们再做一些调整。
1、提示文字的位置
现有的提示文字是在扫描框上面的
我们需要把它放置到扫描框下面,需要将源码中drawTextInfo方法调整一下:
//绘制文本 private void drawTextInfo(Canvas canvas, Rect frame) { ... canvas.drawText(labelText, frame.left + frame.width() / 2, frame.top - CORNER_RECT_HEIGHT, paint); }
调整为:
//绘制文本 private void drawTextInfo(Canvas canvas, Rect frame) { ... canvas.drawText(labelText, frame.left + frame.width() / 2, frame.bottom + CORNER_RECT_HEIGHT * 1.5f, paint); }
此处通过修改drawText的y坐标参数调整了文字位置,可以根据需要自行调整。
2、扫码框的位置
目前的扫码框整体位置偏下,不够美观,打算将位置往上调整一些。
修改com.google.zxing.camera.CameraManager类中的getFramingRect()方法,由
public Rect getFramingRect() { ... int leftOffset = (screenResolution.x - width) / 2; int topOffset = (screenResolution.y - height) / 2; ... return framingRect;}
修改为
public Rect getFramingRect() { ... int leftOffset = (screenResolution.x - width) / 2; int topOffset = (screenResolution.y - height) / 3; ... return framingRect;}
即topOffset有了减小,预览后如:
3、扫码框大小
由2我们可以看到getFramingRect()方法构造的矩形中有宽、高参数,通过修改这两个参数,可以完成扫码框大小变更。例如:
public Rect getFramingRect() { ... int width = screenResolution.x * 8 / 10; int height = screenResolution.y * 8 / 10; ... return framingRect;}
则比原来的代码中放大了1/10,预览图(可对比2中图):
扫码识别优化
这里主要说一下近距离扫码识别不了的问题,关于扫码算法的改进涉猎不多,文尾给大家一篇文章参考。
ZXing在遇到二维码撑满扫码框的情况下识别不出结果,等多久、再聚焦都不可以,有朋友说扩大扫码框的大小可以解决这个问题,扩大后近距离扫码结果还是一致的,很难识别出来。
原因是原算法对摄像头采集的图像像素进行了裁剪,真正返回给识别算法的图像可能没有扫码框那么完整。
参考网络大神的帖子,我们将com.google.zxing.camera.CameraManager类中的buildLuminanceSource方法做了调整,不再返回剪裁后的图像。源码:
public PlanarYUVLuminanceSource buildLuminanceSource(byte[] data, int width, int height) { Rect rect = getFramingRectInPreview(); int previewFormat = configManager.getPreviewFormat(); String previewFormatString = configManager.getPreviewFormatString(); switch (previewFormat) { // This is the standard Android format which all devices are REQUIRED to support. // In theory, it's the only one we should ever care about. case PixelFormat.YCbCr_420_SP: // This format has never been seen in the wild, but is compatible as we only care // about the Y channel, so allow it. case PixelFormat.YCbCr_422_SP: return new PlanarYUVLuminanceSource(data, width, height, rect.left, rect.top, rect.width(), rect.height()); default: // The Samsung Moment incorrectly uses this variant instead of the 'sp' version. // Fortunately, it too has all the Y data up front, so we can read it. if ("yuv420p".equals(previewFormatString)) { return new PlanarYUVLuminanceSource(data, width, height, rect.left, rect.top, rect.width(), rect.height()); } } throw new IllegalArgumentException("Unsupported picture format: " + previewFormat + '/' + previewFormatString); }
修改为:
public PlanarYUVLuminanceSource buildLuminanceSource(byte[] data, int width, int height) { Rect rect = getFramingRectInPreview(); int previewFormat = configManager.getPreviewFormat(); String previewFormatString = configManager.getPreviewFormatString(); switch (previewFormat) { // This is the standard Android format which all devices are REQUIRED to support. // In theory, it's the only one we should ever care about. case PixelFormat.YCbCr_420_SP: // This format has never been seen in the wild, but is compatible as we only care // about the Y channel, so allow it. case PixelFormat.YCbCr_422_SP: return new PlanarYUVLuminanceSource(data, width, height, 0, 0, width, height); default: // The Samsung Moment incorrectly uses this variant instead of the 'sp' version. // Fortunately, it too has all the Y data up front, so we can read it. if ("yuv420p".equals(previewFormatString)) { return new PlanarYUVLuminanceSource(data, width, height, 0, 0, width, height); } } throw new IllegalArgumentException("Unsupported picture format: " + previewFormat + '/' + previewFormatString); }
主要改动的是new PlanarYUVLuminanceSource(data, width, height, 0, 0, width, height); 实际上就是将完整的相机图像内容返回,不做裁剪。
结语
本篇对ZXing扫码工具界面定制和扫码识别优化做了讲解,解决了ZXing近距离无法识别二维码的问题。
大家也可以顺着这个思路,做更多个性化定制和优化,完善扫码功能。
参考资料
http://iluhcm.com/2016/01/08/scan-qr-code-and-recognize-it-from-picture-fastly-using-zxing/
源码下载
csdn上已上传,下载地址:
http://download.csdn.net/detail/ahuyangdong/9915737
- Android实现二维码扫描功能(二)-ZXing个性化与近距离识别优化
- Android实现二维码扫描功能(四)-ZXing识别图片二维码,相册选图
- Zxing 近距离扫描二维码
- Android Zxing实现二维码扫描功能
- Android实现二维码扫描功能(一)-ZXing插件接入
- zxing扫描二维码和识别图片二维码及其优化策略
- zxing扫描二维码和识别图片二维码及其优化策略
- zxing扫描二维码和识别图片二维码及其优化策略
- 使用zxing实现二维码的扫描功能
- Zxing实现安卓二维码扫描功能
- zxing二维码扫描功能
- 二维码生成、扫描、图片识别(Zxing)
- Android生成二维码与识别二维码(ZXing)
- Android Zxing实现二维码、条形码扫描,仿微信二维码扫描效果
- zxing实现二维码扫描
- zxing实现二维码扫描
- android开发之集成zxing,二维码,以及扫描二维码的功能实现。带源代码下载
- Android实现二维码扫描(仿微信,轻量Zxing)
- Javascript 之ArrayLike
- 简单学生管理系统
- LeetCode Longest Substring Without Repeating Characters
- mysql数据库上使用定时器定时执行存储过程建表(月表)
- 【C语言】C语言实现静态顺序表
- Android实现二维码扫描功能(二)-ZXing个性化与近距离识别优化
- SQL Server“复杂”概念之理解
- angular2中ngModel绑定问题
- python 入门系列3:if 语句
- H5 学习笔记5
- C语言——实例026 阶乘
- Tomcat闪退的解决办法
- logutils 一个强大的Android日志管理器【新 https://github.com/orhanobut/logger】
- springcloud学习(五)之hystrix