基于HTML5+tracking.js實(shí)現(xiàn)刷臉支付功能
文章主要介紹了基于HTML5+tracking.js實(shí)現(xiàn)刷臉支付功能,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下...
最近刷臉支付很火,老板們當(dāng)然要追趕時(shí)代潮流,于是就有了刷臉支付這個(gè)項(xiàng)目。前端實(shí)現(xiàn)關(guān)鍵的技術(shù)是攝像頭錄像,拍照和人臉比對(duì),本文來(lái)探討一下如何在html5環(huán)境中如何實(shí)現(xiàn)刷臉支付以及開(kāi)發(fā)過(guò)程中遇到的問(wèn)題。
1.攝像頭1.1input獲取攝像頭
html5中獲取用戶(hù)攝像頭,有兩種方式,使用input,如下:
<input type="file" capture="camera" accept="image/*"/>
另外如果想打開(kāi)相冊(cè),可以這樣:
<
input
type
=
"file"
accept
=
"img/*"
>
但是這兩種方式都會(huì)有兼容性問(wèn)題,用過(guò)的同學(xué)可能都知道。
1.2 getUserMedia獲取攝像圖
getUserMedia是html5一個(gè)新的api,官方一點(diǎn)的定義是:
MediaDevices.getUserMedia()
會(huì)提示用戶(hù)給予使用媒體輸入的許可,媒體輸入會(huì)產(chǎn)生一個(gè)MediaStream
,里面包含了請(qǐng)求的媒體類(lèi)型的軌道。此流可以包含一個(gè)視頻軌道(來(lái)自硬件或者虛擬視頻源,比如相機(jī)、視頻采集設(shè)備和屏幕共享服務(wù)等等)、一個(gè)音頻軌道(同樣來(lái)自硬件或虛擬音頻源,比如麥克風(fēng)、A/D轉(zhuǎn)換器等等),也可能是其它軌道類(lèi)型。
簡(jiǎn)單一點(diǎn)說(shuō)就是可以獲取到用戶(hù)攝像頭。
同上面input一樣,這種方式也有兼容性問(wèn)題,不過(guò)可以使用其他方式解決,這里可以參考MediaDevices.getUserMedia(),文檔中有介紹"在舊的瀏覽器中使用新的API"。我這里在網(wǎng)上也找了一些參考,總結(jié)出一個(gè)相對(duì)全面的getUserMedia版本,代碼如下:
// 訪問(wèn)用戶(hù)媒體設(shè)備
getUserMedia(constrains, success, error) {
????if (navigator.mediaDevices.getUserMedia) {
????????//最新標(biāo)準(zhǔn)API
????????navigator.mediaDevices.getUserMedia(constrains).then(success).catch(error);
????} else if (navigator.webkitGetUserMedia) {
????????//webkit內(nèi)核瀏覽器
????????navigator.webkitGetUserMedia(constrains).then(success).catch(error);
????} else if (navigator.mozGetUserMedia) {
????????//Firefox瀏覽器
????????navagator.mozGetUserMedia(constrains).then(success).catch(error);
????} else if (navigator.getUserMedia) {
????????//舊版API
????????navigator.getUserMedia(constrains).then(success).catch(error);
????} else {
????????this.scanTip = "你的瀏覽器不支持訪問(wèn)用戶(hù)媒體設(shè)備"
????}
}
1.3播放視屏
獲取設(shè)備方法有兩個(gè)回調(diào)函數(shù),一個(gè)是成功,一個(gè)是失敗。成功了就開(kāi)始播放視頻,播放視屏其實(shí)就是給video設(shè)置一個(gè)url,并調(diào)用play方法,這里設(shè)置url要考慮不同瀏覽器兼容性,代碼如下:
success(stream) {
????this.streamIns = stream
????// 設(shè)置播放地址,webkit內(nèi)核瀏覽器
????this.URL = window.URL || window.webkitURL
????if ("srcObject" in this.$refs.refVideo) {
????????this.$refs.refVideo.srcObject = stream
????} else {
????????this.$refs.refVideo.src = this.URL.createObjectURL(stream)
????}
????this.$refs.refVideo.onloadedmetadata = e => {
????????// 播放視頻
????????this.$refs.refVideo.play()
????????this.initTracker()
????}
},
error(e) {
????this.scanTip = "訪問(wèn)用戶(hù)媒體失敗" + e.name + "," + e.message
}
注意:
- 播放視屏方法最好寫(xiě)在onloadmetadata回調(diào)函數(shù)中,否則可能會(huì)報(bào)錯(cuò)。
- 播放視頻的時(shí)候出于安全性考慮,必須在本地環(huán)境中測(cè)試,也就是http://localhost/xxxx中測(cè)試,或者帶有https://xxxxx環(huán)境中測(cè)試,不然的話或有跨域問(wèn)題。
- 下面用到的initTracker()方法也好放在這個(gè)onloadedmetadata回調(diào)函數(shù)里,不然也會(huì)報(bào)錯(cuò)。
2. 捕捉人臉
2.1使用tracking.js捕捉人臉
視屏在video中播放成功之后就開(kāi)始識(shí)別人臉了,這里使用到一個(gè)第三方的功能tracking.js,是國(guó)外的大神寫(xiě)的JavaScript圖像識(shí)別插件。關(guān)鍵代碼如下:
// 人臉捕捉
initTracker() {
????this.context = this.$refs.refCanvas.getContext("2d")??? // 畫(huà)布
????this.tracker = new tracking.ObjectTracker(['face'])???? // tracker實(shí)例
????this.tracker.setStepSize(1.7)?????????????????????????? // 設(shè)置步長(zhǎng)
????this.tracker.on('track', this.handleTracked)??????????? // 綁定監(jiān)聽(tīng)方法
????try {
????????tracking.track('#video', this.tracker)????? // 開(kāi)始追蹤
????} catch (e) {
????????this.scanTip = "訪問(wèn)用戶(hù)媒體失敗,請(qǐng)重試"
????}
}
捕獲到人臉之后,可以在頁(yè)面上用一個(gè)小方框標(biāo)注出來(lái),這樣有點(diǎn)交互效果。
// 追蹤事件
handleTracked(e) {
????if (e.data.length === 0) {
????????this.scanTip = '未檢測(cè)到人臉'
????} else {
????????if (!this.tipFlag) {
????????????this.scanTip = '檢測(cè)成功,正在拍照,請(qǐng)保持不動(dòng)2秒'
????????}
????????// 1秒后拍照,僅拍一次
????????if (!this.flag) {
????????????this.scanTip = '拍照中...'
????????????this.flag = true
????????????this.removePhotoID = setTimeout(() => {
????????????????this.tackPhoto()
????????????????this.tipFlag = true
????????????}, 2000)
????????}
????????e.data.forEach(this.plot)
????}
}
在頁(yè)面中畫(huà)一些方框,標(biāo)識(shí)出人臉:
<div class="rect" v-for="item in profile"
?????????????:style="{ width: item.width + 'px', height: item.height + 'px', left: item.left + 'px', top: item.top + 'px'}"></div>
// 繪制跟蹤框
plot({x, y, width: w, height: h}) {
????// 創(chuàng)建框?qū)ο?
????this.profile.push({ width: w, height: h, left: x, top: y })
}
2.2拍照
拍照,就是使用video作為圖片源,在canvas中保存一張圖片下來(lái),注意這里使用toDataURL方法的時(shí)候可以設(shè)置第二個(gè)參數(shù)quality,從0到1,0表示圖片比較粗糙,但是文件比較小,1表示品質(zhì)最好。
// 拍照
tackPhoto() {
????this.context.drawImage(this.$refs.refVideo, 0, 0, this.screenSize.width, this.screenSize.height)
????// 保存為base64格式
????this.imgUrl = this.saveAsPNG(this.$refs.refCanvas)
????// this.compare(imgUrl)
????this.close()
},
// Base64轉(zhuǎn)文件
getBlobBydataURI(dataURI, type) {
????var binary = window.atob(dataURI.split(',')[1]);
????var array = [];
????for(var i = 0; i < binary.length; i++) {
????????array.push(binary.charCodeAt(i));
????}
????return new Blob([new Uint8Array(array)], {
????????type: type
????});
},
// 保存為png,base64格式圖片
saveAsPNG(c) {
????return c.toDataURL('image/png', 0.3)
}
拍照完成之后就可以把文件發(fā)送給后端,讓后端進(jìn)行對(duì)比驗(yàn)證,這里后端使用的是阿里云的接口。
3.最后效果
3.1參考代碼demo
最后,demo我已經(jīng)放在github上了,感興趣可以打開(kāi)看一下。
效果如下:
3.2在項(xiàng)目中落地
最后放在項(xiàng)目中,無(wú)非就是最后一個(gè)步驟,去調(diào)用接口比對(duì),根據(jù)比對(duì)結(jié)果成功是成功還是失敗,決定是人臉支付還是繼續(xù)使用原來(lái)的密碼支付,效果如下:
ps:這里人臉比對(duì)失敗了,是因?yàn)槲規(guī)е谡郑筒贿谘缆赌樍恕?/p>
總結(jié)
到此這篇關(guān)于基于HTML5+tracking.js實(shí)現(xiàn)刷臉支付功能的文章就介紹到這了,更多相關(guān)html5 刷臉支付內(nèi)容請(qǐng)搜索以前的文章或繼續(xù)瀏覽下面的相關(guān)文章
- HTML5頁(yè)面移動(dòng)端自適應(yīng)布局的實(shí)現(xiàn)示例代碼
- 詳解移動(dòng)端HTML5頁(yè)面根據(jù)屏幕適配的四種方案
- html5 canvas 實(shí)現(xiàn)光線沿不規(guī)則路徑運(yùn)動(dòng)實(shí)例代碼
- html5中使用hotcss.js實(shí)現(xiàn)手機(jī)端自適配的方法
- HTML5網(wǎng)頁(yè)遮罩層 + Iframe實(shí)現(xiàn)界面自動(dòng)顯示的示例代碼
- HTML5通過(guò)navigator.mediaDevices.getUserMedia調(diào)用手
- HTML5中的網(wǎng)絡(luò)存儲(chǔ)實(shí)現(xiàn)方式
- HTML5離線存儲(chǔ)Manifest原理及使用詳解
- HTML5調(diào)用手機(jī)發(fā)短信和打電話功能
- HTML5標(biāo)簽HTMLCollection和NodeList的區(qū)別詳解
HTML5頁(yè)面移動(dòng)端自適應(yīng)布局的實(shí)現(xiàn)示例代碼
文章主要介紹了html5移動(dòng)端自適應(yīng)布局的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。場(chǎng)景:為適應(yīng)各種大小的屏幕自適應(yīng)布局我知道的兩種...
詳解移動(dòng)端HTML5頁(yè)面根據(jù)屏幕適配的四種方案
文章主要介紹了詳解移動(dòng)端h5頁(yè)面根據(jù)屏幕適配的四種方案,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。方法一:引入淘寶開(kāi)源的可伸縮布局方案引...
html5 canvas 實(shí)現(xiàn)光線沿不規(guī)則路徑運(yùn)動(dòng)實(shí)例代碼
文章主要介紹了html5 canvas 實(shí)現(xiàn)光線沿不規(guī)則路徑運(yùn)動(dòng),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下。g讓動(dòng)畫(huà)沿著不規(guī)則路徑運(yùn)動(dòng)查閱svg文檔后發(fā)現(xiàn),svg動(dòng)畫(huà)...
html5中使用hotcss.js實(shí)現(xiàn)手機(jī)端自適配的方法
文章主要介紹了html5中使用hotcss.js實(shí)現(xiàn)手機(jī)端自適配的方法,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下Html5頁(yè)面在手機(jī)端做自適配是很常見(jiàn)的技術(shù)需求,下面...
HTML5網(wǎng)頁(yè)遮罩層 + Iframe實(shí)現(xiàn)界面自動(dòng)顯示的示例代碼
主要介紹了遮罩層 + Iframe實(shí)現(xiàn)界面自動(dòng)顯示的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧前言這周由于科三的考試耽誤了兩天,提前一...
HTML5通過(guò)navigator.mediaDevices.getUserMedia調(diào)用手機(jī)攝像頭問(wèn)題
文章主要介紹了HTML5通過(guò)navigator.mediaDevices.getUserMedia調(diào)用手機(jī)攝像頭問(wèn)題,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下navigator.mediaDevices.getU...
HTML5中的網(wǎng)絡(luò)存儲(chǔ)實(shí)現(xiàn)方式
傳統(tǒng)方式使用document.cookie來(lái)進(jìn)行存儲(chǔ),但是由于其存儲(chǔ)的空間只有4KB左右,并且需要復(fù)雜的操作進(jìn)行解析,給發(fā)開(kāi)者帶來(lái)很多不便,為此,HTML5規(guī)范提出了網(wǎng)絡(luò)存儲(chǔ)的解決方案,本文通過(guò)...
HTML5離線存儲(chǔ)Manifest原理及使用詳解
文章主要介紹了H5離線存儲(chǔ)Manifest原理及使用,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧理解:離線存儲(chǔ)可以將站點(diǎn)的文件儲(chǔ)存在本地,在沒(méi)有網(wǎng)絡(luò)...
HTML5調(diào)用手機(jī)發(fā)短信和打電話功能
文章主要介紹了HTML5調(diào)用手機(jī)發(fā)短信和打電話功能,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下前言本來(lái)感覺(jué)用H5寫(xiě)調(diào)用電話撥號(hào)功能和發(fā)送短信功能會(huì)很不好寫(xiě)...
HTML5標(biāo)簽HTMLCollection和NodeList的區(qū)別詳解
文章主要介紹了HTML5中的HTMLCollection和NodeList的區(qū)別詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧HTML5 HTMLCollection和NodeList的...