uniapp實現人臉識別
- 內容簡介
- 功能實現
- 上傳身份證
- 進行人臉比對
- 遇到的問題
內容簡介
1.拍攝/相冊將身份證照片上傳到接口進行圖片解析
2.使用live-pusher組件拍攝人臉照片,上傳接口與身份證人臉進行比對
功能實現
上傳身份證
先看下效果
![]() | ![]() |
---|
點擊按鈕調用chooseImageAPI進行圖片的上傳
// 上傳按鈕的loading以及disabled狀態,避免多次上傳
const loading = ref(false)
// 上傳按鈕事件
const chooseIdCard = () => {uni.chooseImage({success: (tempFiles) => {// 獲取到當前圖片路徑并調用上傳方法uploadIdCard(tempFiles.tempFilePaths[0])}})
}
// 身份證圖片上傳
const uploadIdCard = async (stream: (ArrayBuffer | string)) => {loading.value = trueuni.uploadFile({url: '/cardInfo/uploads', // 你的上傳接口地址filePath: stream, // 選中的圖片name: 'file', // 與后端協定的keysuccess: ({data, statusCode }) => {if(statusCode == 200){// 這里需要注意下,接口返回的事string,需要解析后才可正常使用const result = JSON.parse(data)if(result.code == 200 || result.success == true){// 這里寫上傳成功的邏輯// 我要將數據存在store中 給后面的頁面使用loading.value = falseconst memberStore = useMemberStore()memberStore.setPersonInfo(result.data)uni.navigateTo({url:'/pages/face/face',})}else{uni.showToast({icon: 'error',title: result.msg})}}},fail: (err) => {console.error(err);uni.showToast({icon: 'error',title: '上傳失敗fail!'})}});
}
進行人臉比對
live-pusher組件實現攝像頭調起以及樣式的實現,在之前的文章有記錄,點擊查看,
這里主要描述該組件截圖上傳的部分
<template><cover-view class="pushContent"><live-pusher id="pusherFaceId" ref="pusherRef" class="livePusher"aspect="1:1" :whiteness="1" :beauty="1" device-position="front"/><cover-image class="pusherImg" src="/static/images/faceRadio.png" alt=""></cover-image></cover-view>
</template>
<script lang="ts" setup>const pusherContext = ref()onMounted(() => {// 獲取當前組件實例const instance = getCurrentInstance() as ComponentInternalInstance;// 創建 live-pusher 上下文 livePusherContext 對象。// 這是要用實例的proxy代理對象pusherContext.value = uni.createLivePusherContext("pusherFaceId", instance.proxy)// 開啟攝像頭預覽pusherContext.value.startPreview({success: () => {// 人臉拍攝上傳faceRecognition()}});})const faceRecognition = () => {pusherContext.value.snapshot({success: (res: UniHelper.LivePusherProps) => {uploadFace(res.message.tempImagePath)},})}const uploadFace = (stream) => {uni.uploadFile({url: '/cardInfo/faceUploads',filePath: stream,name: 'file',// 額外的參數formData: {cardToken: memberStore.personInfo.cardToken},success: ({data, statusCode }) => {if(statusCode == 200){const result = JSON.parse(data)if(result.code == 200 || result.success == true){const memberStore = useMemberStore()memberStore.setProfile(result.data)uni.navigateTo({url:'/pages/main/main',})}else{uni.showToast({icon: 'error',title: result.msg})faceRecognition()}}},fail: (err) => {uni.showToast({icon: 'error',title: '上傳失敗fail!'})}});}
</script>
遇到的問題
- 使用nvue頁進行開發
vue頁面在調用live-pusher組件的API時,不支持回調
人臉拍攝需要在攝像頭調起成功之后進行,并且拍攝快照需要在success回調中獲取值
- 創建 live-pusher 上下文 livePusherContext 對象時要用proxy代理對象
之前使用 getCurrentInstance().ctx 去獲取實例對象,在本地打包以及自定義基座包的時候都沒有問題,但是打正式包就會報錯,導致無法 創建 live-pusher對象,攝像頭黑屏
ctx 和 proxy 的區別
特性 | ctx | proxy |
---|---|---|
適用版本 | Vue 2.x 和 Vue 3.x | Vue 3.x |
推薦使用 | Vue 2.x | Vue 3.x |
訪問方式 | 直接訪問組件實例 | 通過代理對象訪問組件實例 |
安全性 | 較低,直接操作實例可能帶來風險 | 較高,通過代理對象更安全 |
- 流文件上傳
剛開始嘗試用uni.request嘗試上傳流文件,沒成功 。在這個做個記錄
uni實現本地文件轉數據流
- 通過h5+的API FileReader讀取文件 獲得base64地址
- uni中不支持js的FileReader 只支持5+的 API,兩者是有區別的,需要注意下
- uni自帶的API base64ToArrayBuffer 再將base64轉換為buffer
pusherContext.value.snapshot({success: (res: UniHelper.LivePusherProps) => {// 5+API FileReader讀取文件 獲得base64地址const reader = new plus!.io!.FileReader!();reader.readAsDataURL(res.message.tempImagePath)reader.onload = (readerRes: PlusIoFileEvent) => {var speech = readerRes!.target!.result;imgUrl.value = speech// uni自帶的APIbase64ToArrayBuffer 將文件轉換為bufferconst arrayBuffer = uni.base64ToArrayBuffer(speech)const resFace = await faceRecognitionAPI(arrayBuffer)if(resFace.code == 200){isfaced.value = truesetTimeout(() => {uni.navigateTo({url: '/pages/main/main'})}, 1500)}else{uni.showToast({icon: 'error',title: '識別失敗,請對準攝像頭!'})faceRecognition()}}} })