ZXing扫码的优化及module化

ZXing扫码的module化

前言

最近因为因为项目需要,要实现一个二维码扫码功能,作为一个Android开发,首先想到的当然是ZXing,从官网上下载了3.3.3版本,然后本地一编译一运行,可谓是一顿操作猛如虎啊,可惜结果是水土不服,横屏,页面效果,功能过多等等不符合项目需求,于是就走上了项目调整与精简的道路,又考虑到希望后期集成可以更方便的进行,就尝试进行模块化的调整。

一言不合上GIT:ZxingLib

过程

一 移花接木

创建一个项目ZXingLib,然后创建一个Module(ZXingScan),然后把ZXing->android下assets,res,src的内容复制到Module对应目录下。


ZXing扫码的优化及module化_第1张图片
-w429

然后在bulid.gradle下添加如下两个依赖引用

compile 'com.google.zxing:core:3.3.3'
compile 'com.google.zxing:android-core:3.3.0'

并在中配置相关权限申请








在主项目的MainActivity继承CaptureActivity,运行,修改一些报错,直至可以顺利安装。
至此,我们长征的第一步算是顺利达成了。
PS:这边要注意的是因为没有做动态权限认证,相机相关权限可以到设置中手动开启。

二 修剪枝叶

ZXing扫码的优化及module化_第2张图片
-w500

第一步
对上面的一些功能模块整个文件夹,asset文件夹及res下的国际化values都删除。
然后编译并修复一些因为文件删除带来的的报错。主要指CaptureActivity中的一些错误。

handleDecode()方法修改如下

public void handleDecode(Result rawResult, Bitmap barcode, float scaleFactor) {
        inactivityTimer.onActivity();
        lastResult = rawResult;
    }

然后在其中调用的drawResultPoints(),handleDecodeInternally(),handleDecodeExternally()相关方法也进行删除。

第二步
删除余下的不必要的类并进行调整。其中Capture和Decode相关类为核心,需要保留。
另外ViewfinderView主要负责负责扫码界面扫码框及动画处理,接下来打算直接使用xml布局,就把ViewfinderView也删除。移除Preferences相关,设置均设置成默认设置。

精简后的目录结构大概如下


ZXing扫码的优化及module化_第3张图片
-w352

三 精心培育

大枝大叶修改完毕,接下来就是对页面的调整了。
第一步
CaptureActivity中去除除SurfaceView之外所有控件的处理。并添加

protected abstract int getLayoutViewId();

方法,修改onCreate()

setContentView(getLayoutViewId());

同时由主题app提供layout,要注意的是主题app界面中必须要有SurfaceView并且id必须为preview_view


然后在CaptureActivity中设置

 public void handleDecode(Result rawResult, Bitmap barcode, float scaleFactor) {
        inactivityTimer.onActivity();
        onDecodeResult(rawResult, barcode, scaleFactor);
    }

protected abstract void onDecodeResult(Result rawResult, Bitmap barcode, float scaleFactor);

这样就可以实现在主题activity中接收结果并处理了。

到现在为止,我们已经可以进行扫码操作了,可还有一个问题就是,现在条码扫描依然是横屏,这里我们就需要进行转换。

我们找到CameraManager类下的buildLuminanceSource()方法,修改如下

return new PlanarYUVLuminanceSource(data, width, height, rect.left, rect.top,
            rect.width(), rect.height(), false);

修改为

return new PlanarYUVLuminanceSource(rotateYUVDegree90(data, width, height), height, width, 0, 0,
                height, width, false);

其中4、5、6、7参数为解码的范围,我们改成0, 0,height, width,表示全范围扫描,不只限于扫码框范围。
然后height, width表示宽高互换。
并在最后添加

 private byte[] rotateYUVDegree90(byte[] data, int imageWidth, int imageHeight) {
        byte[] yuv = new byte[imageWidth * imageHeight * 3 / 2];
        // Rotate the Y luma
        int i = 0;
        for (int x = 0; x < imageWidth; x++) {
            for (int y = imageHeight - 1; y >= 0; y--) {
                yuv[i] = data[y * imageWidth + x];
                i++;
            }
        }
        // Rotate the U and V color components
        i = imageWidth * imageHeight * 3 / 2 - 1;
        for (int x = imageWidth - 1; x > 0; x = x - 2) {
            for (int y = 0; y < imageHeight / 2; y++) {
                yuv[i] = data[(imageWidth * imageHeight) + (y * imageWidth) + x];
                i--;
                yuv[i] = data[(imageWidth * imageHeight) + (y * imageWidth) + (x - 1)];
                i--;
            }
        }
        return yuv;
    }

用于图片数据的转换。
到此为止,基本可以满足大多数手机的扫码需求了。

四 相机显示优化

到现在为止,我们基本可以很快速的进行扫码识别,但是在某些手机上,特别是现在的全面屏手机,因为较高,所以在竖直方向上总有一些拉升,虽然不影响扫码识别,但看起来总是不舒服,就下来就让我们来看看能不能解决这个问题。

首先在CameraConfigurationManager的initFromCameraParameters(OpenCamera camera) 方法中是设置最佳分辨率的地方。代码如下

cameraResolution = CameraConfigurationUtils.findBestPreviewSizeValue(parameters, screenResolution);
Log.i(TAG, "Camera resolution: " + cameraResolution);
bestPreviewSize = CameraConfigurationUtils.findBestPreviewSizeValue(parameters, screenResolution);
Log.i(TAG, "Best available preview size: " + bestPreviewSize);

哪具体选择哪个分辨率为最佳分辨率就需要看CameraConfigurationUtils.findBestPreviewSizeValue()方法了


ZXing扫码的优化及module化_第4张图片
100

ZXing扫码的优化及module化_第5张图片
200

ZXing扫码的优化及module化_第6张图片
300

findBestPreviewSizeValue()方法具体做了说明,了解了之后我们知道需要对入参做处理
修改如下


-w741

最后大家要是看了觉得还可以,点个赞给个支持呀!

你可能感兴趣的:(ZXing扫码的优化及module化)