博客: 安卓之家
掘金: jp1017
微博: 追风917
CSDN: 蒋朋的家
简书: 追风917
二维码现在用的超级多,其实它就是一种编码,把字符串编码保存成一个图片,我们扫描图片得到字符串就解码成功。
最有名的二维码解析库是 google 出品的 Zxing
,网上也有很多的封装库,有自定义扫描窗口等,更多库请在这个库中搜索 二维码
即可:
安卓各种图片框架
这些库采用的都是手机自带的摄像头,没有USB摄像头,悲催了。
USB摄像头拍照,摄像,网上有一个很牛的开源库:
UVCCamera
我也是参考了这个库,在其基础上开发,主要是采用了test4,开启服务来拍照,摄像。这里有几个坑,耽搁了一整天啊。
这里涉及两方面内容,识别代码和扫描界面
代码里如何实现呢,一开始一点思路都没有啊。
手机摄像头预览识别,可参考:
https://github.com/bingoogolapple/BGAQRCode-Android/issues/55
那么USB摄像头如何实现呢,那么只能到 UVCCamera
这个库里去寻找答案,没办法,只能静下心来好好看。
我的二维码识别也采用了开源库:
https://github.com/yipianfengye/android-zxingLibrary
这个库在使用中有小bug,我都提了PR,自行解决了。
我注意到,该库可以根据 Bitmap
对象识别,那么哪里会有这个对象呢,最先想到的是拍照,点击拍照的时候,一定会有这些数据,那么这些数据在哪里呢,一层一层的剥开,最终在RendererHolder
的 run 方法里找到偶遇 bitmap, 然后他识别二维码的代码移植到这里,点击拍照,果然能识别到二维码,哇哈,成功了一丝丝,最开始以为就先这样实现就可以的。
扫描结束后,要弹个窗口提示下扫描结果啊是不是,这个简单啊,用EventBus啊,然后EventBus一开挂,见证奇迹的时刻:
然而奇迹并没有出现,一直订阅不到,然后各种追寻,未果。
然后尝试了另一个开源库 Router,然而,这个库也没有成功,然后一天就这么嗖嗖的过去了,中间找到 Router的作者,我写了个demo给他,他看后提示我是不是 多进程
,Router 和 EventBus 都是不支持多进程的。
我赶紧去确认了下,该拍照摄像service设置了远程标志:
android:process=":uvcservice"
没跑了,确实跨进程通信了。
那么,怎么搞呢,广播咯,于是用广播实现了扫描后的结果通知。
暂时实现的功能是点击拍照按钮,扫描二维码,这就结束了吗?
界面又该如何实现呢,比如实现微信类似的二维码识别界面。查看了很多自定义二维码识别的界面,都是自定义View,然后重写 onDraw 方法,自定义扫码边框及扫描动画,比如这里:
ViewfinderView
然后查看了下USB摄像库,显示画面的View是继承自 TextureView
的,然后想在此 TextureView
里也重写 onDraw实现,但是发现TextureView里的此方法是final的,也就是不能在绘制别的东西了。查看了下源码,里面的注释里有这样一段话:
It is important to note that only one producer can use the TextureView.
For instance, if you use a TextureView to display the camera preview, you
cannot use {@link #lockCanvas()} to draw onto the TextureView at the same
time.
大体意思就是不能在TextureView上获取Canvas再绘制view,这样看来此路不通啊。
但是有了新的发现,这个发现正好解决了之前的预览识别问题,究竟是什么呢?
TextureView 的使用很简单,两步:
具体使用可查看下面两个文章:
TextureView 使用
TextureView+SurfaceTexture+OpenGL ES来播放视频(二)
在这个listener的源码中,发现 onSurfaceTextureUpdated
方法在每次变化的时候都会调用,也就是预览时会频繁调用,于是,在此方法里打印,果然如此,那么就可以在此方法里去实现预览识别啊。
想法不错,但是该如何去做呢,继续查看UVCCamera源码,发现,里面有个Callback的接口,该接口在拍照的fragment里有实现,但是没有具体实现,而该接口也没有update的调用,于是,我加了个方法:
onSurfaceUpdate(Surface surface);
并实现了该方法,那么剩下的就是在该方法里去扫描二维码,发现TextureView有个方法,getBitmap
,这是极好的,通过此bitmap对象就可以扫描二维码了,bingo。
实际操作,确实也是这样的,哈哈,太棒了,此刻见证了一个真理:
源码是最好的老师
这样,无心插柳,解决了预览识别二维码的问题,但是界面还木有出来啊,怎么弄呢,不能Canvas绘制了,那么就在此TextureView周围添加一个边框吧。
至于扫描动画,也是设置的一个图片的平移动画,没什么可说的,有了思路,剩下的就好办了。
实际图如下:
代码已上传,请到这里查看:
UVCCameraZxing
关于识别图片二维码,也是支持的,很多库都有这个功能的,不难,enjoy!
当然,对于,条形码也是支持的,赶快使用起来吧。
最后,非常感谢您的阅读,有任何疑问,可以后面评论,谢谢!
神奇的安卓开发网站:http://androidcat.com/
安卓开源库收集整理:https://github.com/XXApple/AndroidLibs
分享是一种美德,更是一种生活方式!!
也许你会说我是一个梦想者,但我不是唯一的一个。
悦分享,越快乐^_^
欢迎交流,转载请注明出处,谢谢!