USB攝像頭預覽識別二維碼

博客: 安卓之家 掘金: jp1017 微博: 追風917 CSDN: 蔣朋的家 簡書: 追風917java

每日一景

前言


二維碼如今用的超級多,其實它就是一種編碼,把字符串編碼保存成一個圖片,咱們掃描圖片獲得字符串就解碼成功。android

最有名的二維碼解析庫是 google 出品的 Zxing,網上也有不少的封裝庫,有自定義掃描窗口等,更多庫請在這個庫中搜索 二維碼便可:git

安卓各類圖片框架github

這些庫採用的都是手機自帶的攝像頭,沒有USB攝像頭,悲催了。微信

USB攝像頭拍照,攝像,網上有一個很牛的開源庫:app

UVCCamera框架

我也是參考了這個庫,在其基礎上開發,主要是採用了test4,開啓服務來拍照,攝像。這裏有幾個坑,耽擱了一成天啊。動畫

這裏涉及兩方面內容,識別代碼和掃描界面網站

識別代碼


代碼裏如何實現呢,一開始一點思路都沒有啊。google

手機攝像頭預覽識別,可參考:

github.com/bingoogolap…

那麼USB攝像頭如何實現呢,那麼只能到 UVCCamera 這個庫裏去尋找答案,沒辦法,只能靜下心來好好看。

個人二維碼識別也採用了開源庫:

github.com/yipianfengy…

這個庫在使用中有小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 的使用很簡單,兩步:

  1. 獲取這個TextureView,
  2. 設置setSurfaceTextureListener,實現其四個方法

具體使用可查看下面兩個文章:

TextureView 使用 TextureView+SurfaceTexture+OpenGL ES來播放視頻(二)

在這個listener的源碼中,發現 onSurfaceTextureUpdated 方法在每次變化的時候都會調用,也就是預覽時會頻繁調用,因而,在此方法裏打印,果真如此,那麼就能夠在此方法裏去實現預覽識別啊。

想法不錯,可是該如何去作呢,繼續查看UVCCamera源碼,發現,裏面有個Callback的接口,該接口在拍照的fragment裏有實現,可是沒有具體實現,而該接口也沒有update的調用,因而,我加了個方法:

onSurfaceUpdate(Surface surface);

並實現了該方法,那麼剩下的就是在該方法裏去掃描二維碼,發現TextureView有個方法,getBitmap,這是極好的,經過此bitmap對象就能夠掃描二維碼了,bingo。

實際操做,確實也是這樣的,哈哈,太棒了,此刻見證了一個真理:

源碼是最好的老師

這樣,無意插柳,解決了預覽識別二維碼的問題,可是界面還木有出來啊,怎麼弄呢,不能Canvas繪製了,那麼就在此TextureView周圍添加一個邊框吧。

至於掃描動畫,也是設置的一個圖片的平移動畫,沒什麼可說的,有了思路,剩下的就好辦了。

實際圖以下:

代碼已上傳,請到這裏查看:

UVCCameraZxing

關於識別圖片二維碼,也是支持的,不少庫都有這個功能的,不難,enjoy!

固然,對於,條形碼也是支持的,趕快使用起來吧。

最後,很是感謝您的閱讀,有任何疑問,能夠後面評論,謝謝!

神奇的安卓開發網站:androidcat.com/

安卓開源庫收集整理:github.com/XXApple/And…

分享是一種美德,更是一種生活方式!!

也許你會說我是一個夢想者,但我不是惟一的一個。

悅分享,越快樂^_^

歡迎交流,轉載請註明出處,謝謝!

相關文章
相關標籤/搜索