Zbar扫码优化

项目中有用到二维码扫描的功能,集成zbar后,一切看起来都挺好的,功能都好使,直到使用乐固进行了加固。

加固后的表现简直令人难受,扫描动画几乎停滞,整个界面卡的看起来和使用20kB的网速观看高清视频一样,点击按钮和返回键甚至都没反应或者过了很久才反应。很明显,主线程时间被大幅度占用了。

开始怀疑是加固方有问题,就换用了几个其他的加固方案,比如360加固,发现表现都差不多。然后直接联系乐固的客服,看他们能不能帮助解决。客服和工程师的态度都挺好的,中间各种巴拉巴拉找问题,尝试了好多次,可惜都没有发现问题在哪。

一个星期之后,我觉得靠他们没戏了,开始自己找原因(这里该反省一下,居然拖了一个星期才着手自己解决问题,当然也有乐固的态度太好了给我一种他们能解决问题的错觉o(╯□╰)o)。

最主要关注的地方是各个步骤的处理时间,ZbarZxing有一个不同的地方在于,Zxing使用的是多线程解析,图像解析并不会占用主线程时间,Zbar则没有这么做,怀疑Zbar的性能足够好,不需要开子线程。

通过打log的方式,发现PreviewCallback的回调中,执行一次解析的时间最多的一次足足超过了181ms(加固后),最短的一次也有130ms,一秒钟可能会解析很多次,这样不卡才怪。

Zbar的回调中是按照这样的步骤来处理从相机拿到的数据的:

1.翻转相机的数据,因为android相机默认拿的横屏的数据。ZbarCameraConfigurationManager中其实已经设置了竖屏预览(setDisplayOrientation(90),但是这里从PreviewCallback中返回的数据依然是横屏的。相机返回的数据是一个byte数组(YUV格式),这个数组的长度是CameragetPreviewSize()方法返回的尺寸的width*height*1.5,其中前面width*height存储像素点

Zbar源码中这样翻转数据:

 

byte[] rotatedData = new byte[data.length];
for (int y = 0; y < size.height; y++) {
for (int x = 0; x < size.width; x++)
rotatedData[x * size.height + size.height - y - 1] = data[x
+ y * size.width];
}
 
// 宽高也要调整
int tmp = size.width;
size.width = size.height;
size.height = tmp;

 

2.初始化截取的矩形区域。扫码的话,并不需要解析整个图片,而是二维码所在的区域,这里是生成二维码取景框的区域。

3.使用Zbar进行图像解析。

这里主要的耗时发生在第一步和第三步上面。第三步的话最终调用的Native方法,不太好改,所以优化主要集中在第一步上面。

对于第一步的处理是这样考虑的:扫码的话,不在乎是横屏还是竖屏,所以这里没有必要翻转数据,第一步的时间开销其实是没有必要的。这里的重点是不翻转数据了,那么需要处理的图像数据范围就从原来的竖屏变成了横屏,方法如下:

Rect convertCrop(Rect src) {
            int cameraHeight = mCameraManager.getCameraResolution().y;
            Rect rect = new Rect();
            rect.left = src.top;
            rect.right = rect.left + src.height();
            rect.top = cameraHeight - (src.left + src.width());
            rect.bottom = rect.top + src.width();
            return rect;
        }

 

处理完之后,再使用乐固进行加固,果然不在卡顿了,谢天谢地。

 

 

你可能感兴趣的:(Android相关)