周日在酒店擼了一下午,加晚上到12點(diǎn),終于把攝像頭掃碼的 Java 版本擼了個(gè)大概。
可以實(shí)現(xiàn)的效果就是打開攝像頭掃描一張二維碼圖片然后顯示二維碼里面的內(nèi)容,看個(gè)視頻一睹為快吧(界面待優(yōu)化):
可以看到二維碼掃描成功之后會(huì)在屏幕底下彈出一個(gè)帶有內(nèi)容的氣泡。
其實(shí)我也不知道是怎么回事,對(duì)于掃碼這么高頻的需求官方竟然沒有集成進(jìn)來。
PS:最新的消息 js 已經(jīng)集成了,但是 java 還沒有,只有一個(gè)生成二維碼的代碼。
我翻了全網(wǎng)的文檔找到了幾個(gè)相關(guān)的:
①這個(gè)是官方的 codelabs 的一篇帖子,無法模擬運(yùn)行,就等于是個(gè)帖子,而且這帖子還被許多網(wǎng)友搬到了博客上。
https://developer.huawei.com/consumer/cn/codelabsPortal/carddetails/HarmonyOS-QRCode
這個(gè)帖子本身沒毛病,但是他最大的問題就是沒搞定,具體說來就是給你一個(gè)模糊的基礎(chǔ)讓你知道怎么回事而已,但是這帖子有一些可取的地方我們稍后再說。
②這個(gè)是 HarmonyOS 的官方開發(fā)文檔,里面有介紹怎么啟用相機(jī)拍照,錄視頻。
https://developer.harmonyos.com/cn/docs/documentation/doc-guides/media-camera-guidelines-0000000000031782
這個(gè)文檔最大的作用就是告訴你怎么操作攝像頭,但是對(duì)于掃碼,只字未提。
③這個(gè)基本沒用,只有碼生成而沒有解析,差評(píng)。
https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ai-code-genration-overview-0000001051062161
④這個(gè)帖子是 javaAPI 的使用手冊(cè),同樣只有碼生成而沒有解析,還是差評(píng)。
https://developer.harmonyos.com/cn/docs/documentation/doc-references/ibarcodedetector-0000001054120097
翻了一堆的帖子,我就納悶了,二維碼掃描這東西都出來這么多年了,技術(shù)上有啥難題嗎,怎么全網(wǎng)都沒有在弄的。
要知道,微信小程序里面可是直接自帶掃碼接口的呀!既然沒有,就到了咱顯一顯身手的時(shí)候了,哈哈!
技術(shù)思路
其實(shí)思路基本沒啥,咱們?nèi)粘I钪信龅綊呙锜o非是三種:
攝像頭掃碼
圖片直接解
在微信上比較常見的長(zhǎng)按某張圖片幫你掃碼,其實(shí)就是圖片掃碼一樣的
這里咱們著重處理攝像頭掃碼,因?yàn)閳D片掃描是攝像頭掃碼后面那部分,就是你攝像頭已經(jīng)取得圖片了,然后再解析掃碼。
可以這樣說:如果你學(xué)會(huì)了攝像頭掃碼,那么圖片解析二維碼你自動(dòng)就會(huì)了,怎么樣,是不是很心動(dòng),快跟我學(xué)起來吧!
原理:啟用手機(jī)攝像頭→攝像頭預(yù)覽→對(duì)準(zhǔn)二維碼→解析攝像頭數(shù)據(jù)→保存成圖片→發(fā)給二維碼解析庫(kù)解析→獲取解析結(jié)果。
開工
①打開你的手機(jī)攝像頭
攝像頭的啟用,怎么拍圖片在這篇官方文檔上講的很清楚了:
https://developer.harmonyos.com/cn/docs/documentation/doc-guides/media-camera-guidelines-0000000000031782而且文檔下面還有一個(gè) gitee 倉(cāng)庫(kù)給你看源碼,這塊我尋思不用多講吧:
https://gitee.com/harmonyos/harmonyos_app_samples/tree/master/media/Camera
請(qǐng)首先順利得能讓你的手機(jī)拍一張照片出來,提示,此處有坑:真機(jī)調(diào)試時(shí)需要在手機(jī)權(quán)限里手動(dòng)把攝像頭權(quán)限打開,否則你得到的是一個(gè)黑屏。
這個(gè)問題折騰了我半個(gè)小時(shí),我以為在代碼里面加了權(quán)限,而手機(jī)也沒有彈出權(quán)限提示框就以為權(quán)限是正常的,結(jié)果進(jìn)到設(shè)置一看尼瑪禁的死死的。
②把官方代碼的圖片保存函數(shù)替換掉
其實(shí)就是這個(gè)函數(shù):
privatevoidsaveImage(ImageReceiverreceiver)
怎么改呢?咱有參考,還記得上面提到的官方 codelabs 嗎?對(duì)就是他:
https://developer.huawei.com/consumer/cn/codelabsPortal/carddetails/HarmonyOS-QRCode
這地方有怎么把你拍到的圖片轉(zhuǎn)換成 Pixel 像素圖。
③上大招:zxing 閃亮登場(chǎng)
以下為心路歷程:在官方的那個(gè) codelabs 里面,最后一句話他說:—-結(jié)束。
what?怎么就結(jié)束了?當(dāng)時(shí)給我看的那叫懵啊,不過好在咱有邏輯思維分析能力,往上翻,上一篇叫二維碼識(shí)別,好,看吧:
哦哦,引入一下這三個(gè)文件是吧,簡(jiǎn)單,我找一下哈…
請(qǐng)問文件在哪?唉不整了,玩?zhèn)€游戲先...打了會(huì)游戲,又覺無聊,唉,還是學(xué)習(xí)吧,誰叫咱熱愛學(xué)習(xí)呢?
幾經(jīng)搜索,給我找到了一個(gè)叫做 zxing 的庫(kù),這個(gè)庫(kù)著實(shí)強(qiáng)大,谷歌官方維護(hù)的,翻譯一下這就叫驚喜,二話不多整活了。
下載 zxing 庫(kù):官方網(wǎng)址如下,最新版是 3.4.1,直接下載過來。
https://github.com/zxing/zxing
打開來一看,都是啥:
這里面東西不少,但憑著咱技術(shù)人的直覺,自己只需要里面的 core,但是要怎么使用呢?官方 readme 上面有一句話:
那咱打開吧:
https://github.com/zxing/zxing/wiki/Getting-Started-Developing
這里面有一句話引發(fā)了我的思考:
對(duì),說到心坎里了,我只要一個(gè) jar 包。合著前面的下載白弄了…
其實(shí)有更好的方式:根據(jù)自己的悟性領(lǐng)悟了,Maven 轉(zhuǎn) gradle 的方式,直接在項(xiàng)目 build.gradle 里面加一句。
改完這個(gè)文件,ide 提示你要同步一下,點(diǎn)擊同步,這時(shí)候 zxing-core 就集成到你的項(xiàng)目中了,方便。
集成,集成:這塊我直接貼代碼吧,講起來有點(diǎn)啰嗦。
privatevoidsaveImage(ImageReceiverreceiver){ HiLog.info(LABEL_LOG,"==>saveImage"); ohos.media.image.Imageimage=receiver.readNextImage(); ohos.media.image.Image.Componentcomponent=image.getComponent(ImageFormat.ComponentType.JPEG); byte[]jpgbytes=newbyte[component.remaining()]; component.read(jpgbytes); HiLog.info(LABEL_LOG,"....==>saveImage:%{public}d",jpgbytes.length); ImageSource.SourceOptionssourceOptions=newImageSource.SourceOptions(); sourceOptions.formatHint="image/jpg"; ImageSourceimageSource=ImageSource.create(jpgbytes,sourceOptions); PixelMappixelMap=imageSource.createPixelmap(null); intwidth=pixelMap.getImageInfo().size.width; intheight=pixelMap.getImageInfo().size.height; int[]pis=newint[width*height]; HiLog.info(LABEL_LOG,"pixnumberbyte%{public}d,size==>%{public}s"+ "w%{public}dh%{public}d", pixelMap.getPixelBytesNumber(), pixelMap.getBytesNumberPerRow(), width,height); try{ pixelMap.readPixels(pis,0,width,newRect(0,0,width,height)); }catch(Exceptione){ HiLog.error(LABEL_LOG,"readPixelserror:%{public}s",e.toString()); return; } RGBLuminanceSourcergbSource=newRGBLuminanceSource( pixelMap.getImageInfo().size.width,pixelMap.getImageInfo().size.height,pis); HiLog.info(LABEL_LOG,"source:%{public}s",rgbSource.toString()); LuminanceSourcesource=rgbSource.crop(0,0,rgbSource.getWidth(),rgbSource.getHeight()); BinaryBitmapbMap=newBinaryBitmap(newHybridBinarizer(source)); finalMaphints=newHashMap<>(); hints.put(DecodeHintType.CHARACTER_SET,"utf-8"); hints.put(DecodeHintType.POSSIBLE_FORMATS,BarcodeFormat.QR_CODE); hints.put(DecodeHintType.TRY_HARDER,Boolean.TRUE); QRCodeReaderreader=newQRCodeReader(); Resultresult=null; try{ result=reader.decode(bMap,hints); HiLog.info(LABEL_LOG,"==>result:"+result.toString()); showTips(this.getContext(),result.toString()); }catch(NotFoundExceptione){ HiLog.info(LABEL_LOG,"notfound:"+e.toString()); }catch(Exceptione){ HiLog.error(LABEL_LOG,"catchException:"+e.toString()); } }
短短的 60 行左右就搞定了(實(shí)際上折騰了 5Hour+),前面一直到第 13 行大家都能看懂,就是轉(zhuǎn)換 Pixel 圖片,不懂的同學(xué)往上翻去復(fù)習(xí)哈。 后面就是把像素取出來,傳給 zxing 去解析,核心代碼在 QRcode.decode() 這里,前面的都是輔料。
打完收工:到這里我 java 版本的二維碼識(shí)別掃描就初步完成了,大家可以行測(cè)試了。
總結(jié)
是不是感覺挺簡(jiǎn)單的,說來也是奇怪,這么簡(jiǎn)單的東西為啥就是沒人做呢?借星光計(jì)劃給大家發(fā)第一篇文章,一起期待下一篇吧!
原文標(biāo)題:60行代碼搞定鴻蒙“二維碼掃描”功能!
文章出處:【微信公眾號(hào):HarmonyOS技術(shù)社區(qū)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
-
JAVA
+關(guān)注
關(guān)注
19文章
2973瀏覽量
104908 -
攝像頭
+關(guān)注
關(guān)注
60文章
4856瀏覽量
95990 -
鴻蒙
+關(guān)注
關(guān)注
57文章
2378瀏覽量
42940
原文標(biāo)題:60行代碼搞定鴻蒙“二維碼掃描”功能!
文章出處:【微信號(hào):gh_834c4b3d87fe,微信公眾號(hào):OpenHarmony技術(shù)社區(qū)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論