Android笔记之zxing官方demo支持竖屏
来源:互联网 发布:cnc立式宏程序编程实例 编辑:程序博客网 时间:2024/05/18 13:44
在这篇文章之前,如果还不知道如何下载、运行官方demo,打包zxing jar包,请跳到
http://blog.csdn.net/quwei3930921/article/details/51206245
1.在AndroidManifest.xml中,把Activity的属性
android:screenOrientation="landscape"
改为
android:screenOrientation="portrait"
2.在CameraManager.java文件中,选择框调整
原代码:
public synchronized Rect getFramingRect() { if (framingRect == null) { if (camera == null) { return null; } Point screenResolution = configManager.getScreenResolution(); if (screenResolution == null) { // Called early, before init even finished return null; } int width = findDesiredDimensionInRange(screenResolution.x, MIN_FRAME_WIDTH, MAX_FRAME_WIDTH); int height = findDesiredDimensionInRange(screenResolution.y, MIN_FRAME_HEIGHT, MAX_FRAME_HEIGHT); int leftOffset = (screenResolution.x - width) / 2; int topOffset = (screenResolution.y - height) / 2; framingRect = new Rect(leftOffset, topOffset, leftOffset + width, topOffset + height); Log.d(TAG, "Calculated framing rect: " + framingRect); } return framingRect; }
修改为
public synchronized Rect getFramingRect() { if (framingRect == null) { if (camera == null) { return null; } Point screenResolution = configManager.getScreenResolution(); if (screenResolution == null) { // Called early, before init even finished return null; } // 修改开始 int width, height, leftOffset, topOffset; if (screenResolution.x < screenResolution.y) { // 竖屏 width = screenResolution.x * 9 / 10; height = width * 9 / 16; // 采用16:9的比例 leftOffset = (screenResolution.x - width) / 2; topOffset = (screenResolution.y - height) / 2; } else { height = screenResolution.y * 5 / 10; width = height * 16 / 9; leftOffset = (screenResolution.x - width) / 2; topOffset = (screenResolution.y - height) / 2; } // 修改完成 framingRect = new Rect(leftOffset, topOffset, leftOffset + width, topOffset + height); Log.d(TAG, "Calculated framing rect: " + framingRect); } return framingRect; }
3.在CameraManager.java文件中,修改预览缩放
原代码:
public synchronized Rect getFramingRectInPreview() { if (framingRectInPreview == null) { Rect framingRect = getFramingRect(); if (framingRect == null) { return null; } Rect rect = new Rect(framingRect); Point cameraResolution = configManager.getCameraResolution(); Point screenResolution = configManager.getScreenResolution(); if (cameraResolution == null || screenResolution == null) { // Called early, before init even finished return null; } rect.left = rect.left * cameraResolution.x / screenResolution.x; rect.right = rect.right * cameraResolution.x / screenResolution.x; rect.top = rect.top * cameraResolution.y / screenResolution.y; rect.bottom = rect.bottom * cameraResolution.y / screenResolution.y; framingRectInPreview = rect; } return framingRectInPreview; }
修改为
public synchronized Rect getFramingRectInPreview() { if (framingRectInPreview == null) { Rect framingRect = getFramingRect(); if (framingRect == null) { return null; } Rect rect = new Rect(framingRect); Point cameraResolution = configManager.getCameraResolution(); Point screenResolution = configManager.getScreenResolution(); if (cameraResolution == null || screenResolution == null) { // Called early, before init even finished return null; } // 修改开始 if (screenResolution.x < screenResolution.y) { // 下面为竖屏模式 rect.left = framingRect.left * cameraResolution.y / screenResolution.x; rect.right = framingRect.right * cameraResolution.y / screenResolution.x; rect.top = framingRect.top * cameraResolution.x / screenResolution.y; rect.bottom = framingRect.bottom * cameraResolution.x / screenResolution.y; } else { // 下面为横屏模式 rect.left = framingRect.left * cameraResolution.x / screenResolution.x; rect.right = framingRect.right * cameraResolution.x / screenResolution.x; rect.top = framingRect.top * cameraResolution.y / screenResolution.y; rect.bottom = framingRect.bottom * cameraResolution.y / screenResolution.y; } // 修改完成 framingRectInPreview = rect; } return framingRectInPreview; }
4.在CameraManager.java文件中,修改解析函数
原代码:
public PlanarYUVLuminanceSource buildLuminanceSource(byte[] data, int width, int height) { Rect rect = getFramingRectInPreview(); if (rect == null) { return null; } // Go ahead and assume it's YUV rather than die. return new PlanarYUVLuminanceSource(data, width, height, rect.left, rect.top, rect.width(), rect.height(), false); }
修改后:
public PlanarYUVLuminanceSource buildLuminanceSource(byte[] data, int width, int height) { Rect rect = getFramingRectInPreview(); if (rect == null) { return null; } // 修改开始 PlanarYUVLuminanceSource source; Point point = configManager.getScreenResolution(); if (point.x < point.y) { // 竖屏对应修改,条码解析默认是横向解析 byte[] rotatedData = new byte[data.length]; int newWidth = height; int newHeight = width; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) rotatedData[x * newWidth + newWidth - 1 - y] = data[x + y * width]; } source = new PlanarYUVLuminanceSource(rotatedData, newWidth, newHeight, rect.left, rect.top, rect.width(), rect.height(), false); } else { source = new PlanarYUVLuminanceSource(data, width, height, rect.left, rect.top, rect.width(), rect.height(), false); } // 修改完成 return source; }
5.在CameraConfigurationUtils.java文件中,我们在findBestPreviewSizeValue方法找到以下代码
boolean isCandidatePortrait = realWidth < realHeight; int maybeFlippedWidth = isCandidatePortrait ? realHeight : realWidth; int maybeFlippedHeight = isCandidatePortrait ? realWidth : realHeight; double aspectRatio = (double) maybeFlippedWidth / (double) maybeFlippedHeight; double distortion = Math.abs(aspectRatio - screenAspectRatio); if (distortion > MAX_ASPECT_DISTORTION) { it.remove(); continue; }
这段代码用于排除镜头分辨率纵横比例与屏幕分辨率纵横比例相差较大的镜头分辨率,还有一点就是上述代码aspectRatio的值始终是大值比小值,那么screenAspectRatio的值也应该是大值比小值。我们在该方法中找到screenAspectRatio的赋值语句:
double screenAspectRatio = (double) screenResolution.x / (double) screenResolution.y;
对于竖屏这里明显是不正确的,所以修改为
double screenAspectRatio; if (screenResolution.x < screenResolution.y) { // 竖屏 screenAspectRatio = (double) screenResolution.y / (double) screenResolution.x; } else { screenAspectRatio = (double) screenResolution.x / (double) screenResolution.y; }
再这个函数中,还有个地方要注意,因为它直接影响到识别的速度和准确率:
if (maybeFlippedWidth == screenResolution.x && maybeFlippedHeight == screenResolution.y) { Point exactPoint = new Point(realWidth, realHeight); Log.i(TAG, "Found preview size exactly matching screen size: " + exactPoint); return exactPoint; }
对于镜头分辨率高,而屏幕分辨率低的手机,这段代码直接导致zxing会采用较低的分辨率去生成用于解析的位图,所以直接去掉。然后你就会发现低分辨率的手机,对二维码、条码的识别率提高了n个级别。
6.在CameraConfigurationManager.java文件中,在setDesiredCameraParameters方法中找到:
parameters.setPreviewSize(bestPreviewSize.x, bestPreviewSize.y);
在该代码上方添加对焦距的调整,让识别效果更加快速、准确:
CameraConfigurationUtils.setZoom(parameters, 1.5); parameters.setPreviewSize(bestPreviewSize.x, bestPreviewSize.y);
总结,为了公司app较好的对条码的识别,zxing的demo也来回读了很多遍,最后得出以上调整。同时支持横竖屏,只需在manifest中设置即可。识别速度快、准,与微信基本没差距,领导、用户都很满意。如果还有什么问题,请留言。
- Android笔记之zxing官方demo支持竖屏
- ZXing官方项目Demo还原 (eclipse 版本)
- android笔记之zxing生成二维码、条码
- Android集成ZXing二维码扫描,附加竖屏并且不拉伸图片的demo
- android zxing使用笔记
- android 官方demo地址
- android zxing 定制竖屏
- Zxing 竖屏切换 android
- Zxing 竖屏切换 android
- Android ZXing竖屏解决
- Zxing 竖屏切换 Android
- Android之zxing二维码
- Android之二维码zxing
- Android二维码之zxing
- ZXing 官方项目还原(Android Studio 版本)
- Android Zxing 扫描的简单的demo
- android ZXing 二维码的实现与demo
- Android酱油笔记之关于ZXing二维码项目
- apache2.4服务安装步骤
- 用keil仿真时显示*** WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS *** WARNING L16: UNC
- POJ-1191 棋盘分割
- WH服务器框架分析系列三:WH服务器逻辑线程对象
- Hadoop+HBase+ZooKeeper三者关系与安装配置
- Android笔记之zxing官方demo支持竖屏
- Vim 小技巧
- Hbase配置项粗解
- 51单片机程序错误,无法编译?怎么搞好STC15F
- 百度地图 多轨迹 示例
- MyBatis参数传入集合之foreach动态sql
- JAVA简单的性能调优
- 史上短小精悍的JavaScript编写的俄罗斯方块游戏
- 警告:directory not found for option"XXXXXX"