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()}}} })