zxing二维码扫描性能体验完全优化攻略

背景

zxing是使用最广泛二维码扫描库,提升体验是非常必要的,最近做了下优化,在实际使用发现了很多,给大家分享下

正文

基础优化

首先参照网上一些优化方法,主要是:
https://toutiao.io/posts/d5buuo/preview
https://www.jianshu.com/p/d10e147a2709

必须加的

  1. 去除额外格式
  2. 减少解码数据 裁减无用区域
  3. 选择合适的相机preview size

需要改造,作用比较小的

  1. 将处理相机帧从串行改为并行

有坑的:

  1. 自动放大
    检测到结果后再放大,那再进行的放大没有意义,除非自己增加判断二维码存在的算法
  2. 解码算法优化
    原文:”使用GlobalHistogramBinarizer算法的效果要稍微比HybridBinarizer好一些,识别的速度更快。”
    实际官方推荐的是HybridBinarizer,识别效果更好,解码处理的时间基本都是非常快的,瓶颈不在这里,

必须项在项目中已经支持,然后尝试了其它,最后加上了处理并行发现实际优化极小。

进一步探索

定位各个步骤所需时间,发现最大的耗时是相机的时间,解码的时间低端手机也只有几十毫秒,高端手机不到10ms。

二维码扫描体验做得最好的微信和支付宝,界面响应速度非常快,进入后过一瞬才会相机显示出来。而普通的二维码加载进行页面慢,然后会加动画。

所以这里我们可以做

  1. 去除acitivty动画。
    现在很多activity进入有个左移动画,对于二维码扫描页没有必要,参考微信支付宝都是直接加载的。
  2. 相机异步加载
    相机可以异步先加载,然后进行显示,这样能加快一点打开时间

这时从打开页面到扫描成功速度能从1200ms提升至1100ms左右

深入改造

加上异步打开相机后,相机打开后会有一次重新对焦的过程,经过调研发现是相机API1机制问题!
相机显示与解码对应了两路流,设置了两次回调setPreviewDisplay和setPreviewCallback。不加异步没问题是相机设置成功后再显示,这样就慢了。

想到解决方案有两种:

  1. 使用API1,setPreviewCallback回调的yuv数据同时用于显示和解码,这样就需要自己做yuv数据处理和渲染,使用opengl可以解决
  2. 使用API2,相机底层机制解决了这些问题,但对于APP需要兼容5.0以下使用API1

不能被过去束缚,要拥抱新的东西,也为了整体逻辑更轻松,为来更易维护,最终决定使用方法2,整体重写zxing的相机逻辑。
增加相机接口,做API1和AP2的两套实现,保留解码部分逻辑,具体就不介绍了。

做了开关控制API1切换,最终的效果还挺好,整体时间提升至700-800ms范围,没有再次对焦的问题。

结果数据

打印了快如闪点demo里面的时间作为对比,从onCreate到扫描成功,在1100-1200的范围内
2020-08-31 18:45:02.250 4350-4350/com.zhouk.qrzxingscan D/QRScanActivity1: onCreate
2020-08-31 18:45:03.290 4350-4350/com.zhouk.qrzxingscan D/QRScanActivity1: scanResult time:1067
2020-08-31 18:45:03.860 4350-4350/com.zhouk.qrzxingscan D/QRScanActivity1: onCreate
2020-08-31 18:45:05.070 4350-4350/com.zhouk.qrzxingscan D/QRScanActivity1: scanResult time:1226
2020-08-31 18:45:05.710 4350-4350/com.zhouk.qrzxingscan D/QRScanActivity1: onCreate
2020-08-31 18:45:06.883 4350-4350/com.zhouk.qrzxingscan D/QRScanActivity1: scanResult time:1189
2020-08-31 18:45:07.421 4350-4350/com.zhouk.qrzxingscan D/QRScanActivity1: onCreate
2020-08-31 18:45:08.599 4350-4350/com.zhouk.qrzxingscan D/QRScanActivity1: scanResult time:1192
2020-08-31 18:45:09.009 4350-4350/com.zhouk.qrzxingscan D/QRScanActivity1: onCreate
2020-08-31 18:45:10.213 4350-4350/com.zhouk.qrzxingscan D/QRScanActivity1: scanResult time:1220
2020-08-31 18:45:10.774 4350-4350/com.zhouk.qrzxingscan D/QRScanActivity1: onCreate
2020-08-31 18:45:11.937 4350-4350/com.zhouk.qrzxingscan D/QRScanActivity1: scanResult time:1179
2020-08-31 18:45:12.494 4350-4350/com.zhouk.qrzxingscan D/QRScanActivity1: onCreate
2020-08-31 18:45:13.616 4350-4350/com.zhouk.qrzxingscan D/QRScanActivity1: scanResult time:1137
2020-08-31 18:45:14.182 4350-4350/com.zhouk.qrzxingscan D/QRScanActivity1: onCreate
2020-08-31 18:45:15.329 4350-4350/com.zhouk.qrzxingscan D/QRScanActivity1: scanResult time:1161
2020-08-31 18:45:15.913 4350-4350/com.zhouk.qrzxingscan D/QRScanActivity1: onCreate
2020-08-31 18:45:17.065 4350-4350/com.zhouk.qrzxingscan D/QRScanActivity1: scanResult time:1165

我优化后自测小米10 pro时间:

使用API1:
2020-08-25 14:31:57.803 13916-13916/com.xiaomi.smarthome D/ScanBarcodeActivity: decode time from create:1190
2020-08-25 14:31:59.868 13916-13916/com.xiaomi.smarthome D/ScanBarcodeActivity: decode time from create:1200
2020-08-25 14:32:01.964 13916-13916/com.xiaomi.smarthome D/ScanBarcodeActivity: decode time from create:1218
2020-08-25 14:32:03.828 13916-13916/com.xiaomi.smarthome D/ScanBarcodeActivity: decode time from create:1118
2020-08-25 14:32:05.769 13916-13916/com.xiaomi.smarthome D/ScanBarcodeActivity: decode time from create:1184
2020-08-25 14:32:08.025 13916-13916/com.xiaomi.smarthome D/ScanBarcodeActivity: decode time from create:1187
2020-08-25 14:32:09.915 13916-13916/com.xiaomi.smarthome D/ScanBarcodeActivity: decode time from create:1180
2020-08-25 14:32:11.791 13916-13916/com.xiaomi.smarthome D/ScanBarcodeActivity: decode time from create:1194

使用API2:
2020-08-25 14:32:28.475 13916-13916/com.xiaomi.smarthome D/ScanBarcodeActivity: decode time from create:809
2020-08-25 14:32:31.822 13916-13916/com.xiaomi.smarthome D/ScanBarcodeActivity: decode time from create:702
2020-08-25 14:32:33.890 13916-13916/com.xiaomi.smarthome D/ScanBarcodeActivity: decode time from create:682
2020-08-25 14:32:35.372 13916-13916/com.xiaomi.smarthome D/ScanBarcodeActivity: decode time from create:777
2020-08-25 14:32:36.702 13916-13916/com.xiaomi.smarthome D/ScanBarcodeActivity: decode time from create:752
2020-08-25 14:32:37.954 13916-13916/com.xiaomi.smarthome D/ScanBarcodeActivity: decode time from create:693
2020-08-25 14:32:39.354 13916-13916/com.xiaomi.smarthome D/ScanBarcodeActivity: decode time from create:793
2020-08-25 14:32:40.688 13916-13916/com.xiaomi.smarthome D/ScanBarcodeActivity: decode time from create:793

总结

整体优化测试手机是小米10Pro,特点是四摄相机较重,处理速度快,不同手机上会有些差别。
具体解决问题不难,难在分析和找问题,再次对焦的问题就找了两天。然后要看实际结果数据分析,根据实际情况选用方案。具体编码都是次要的了。