最新提示:微信小程序上线前审核,要求你必须使用微信自带活体识别的sdk,自己开发的不会被允许通过,望周知!
这相信有很多小程序都会用,为啥呢?因为小程序压根不得给你用户身份证信息,所以替换做法就是你让用户上传身份证照片,然后你在人脸识别,判断是同一个人后,再将你信息录入数据库
1、在小程序端的活体识别方法
1、uniapp camera组件拍照 takePhoto
2、uniapp camera组件录像 startRecord
3、uniapp live-pusher组件 视频推流方式
2、拍照方式实现人脸识别
因为项目要得紧,所以我这里使用最简单的拍照,拍八张,定时器每秒一张(后端用的是百度人脸识别api,有照片活体识别和视频活体识别),然后一起传给后端,不过更好的做法是拍一张传一张,成功则完成,识别失败那就再调拍照api,总的时间不超过十秒,在用户端看来是没有任何异常的。
<template>
<view class="face-detection">
<view class="live-father">
<view v-if="status==-1" class="camera-box">
<view class="camera-tip">
<image class="controls-play" src="../../static/img/own/face.png" mode=""></image>
</view>
</view>
<camera v-else class="camera-box" device-position="front" flash="off" @initdone="initdone" @stop="stop"
@error="error">
<cover-view class="camera-tip">
<cover-image class="controls-play" src="../../static/img/own/face.png"></cover-image>
</cover-view>
</camera>
</view>
<button class="bottom" type="primary" :disabled="status==1" @click="startFace">{{statusFilter()}}</button>
</view>
</template>
<script setup>
import {
ref,
reactive,
computed,
getCurrentInstance,
onBeforeUnmount,
watch
} from 'vue'
import {
onLoad,
onReady,
onHide,
onError
} from '@dcloudio/uni-app'
import { pullAuth } from '@/utils'
const {
proxy
} = getCurrentInstance()
const context = ref(null)
onHide(() => {
photoStatus(3)
})
onError(() => {
photoStatus(3)
})
onBeforeUnmount(() => {
console.log(1);
photoStatus()
})
const flag = ref(0)
const time = ref(0) // 重新调用接口限制为10次
const ctx = ref(null) // 相机对象
const realUser = reactive({
name: '',
idNumber: ''
})
/**
* 相机初始化完成
*/
const initdone = () => {
console.log(2);
photoStatus()
}
const startFace = () => {
pullAuth('scope.camera', firstSuccess, firstFail)
}
/**
* 相机状态回调
*/
const photoStatus = (type = 0) => {
status.value = type
}
const status = ref(-1) // -1 => 相机未就绪,申请摄像头权限, 0 => 相机已就绪,但未开始, 1 => 进行中, 2 => 已结束, 3 => 重新识别
const statusFilter = () => {
switch (status.value) {
case -1:
return '开始识别'
case 0:
return '开始识别'
case 1:
return '正在识别中...'
case 2:
return '识别完成'
case 3:
return '重新识别'
default:
return '开始识别'
}
}
/**
* 拍照
*/
const takePhoto = () => {
time.value++
photoStatus(1)
ctx.value.takePhoto({
quality: 'high',
success: (result) => {
proxy.$api.user.faceRecognition({
file: result.tempImagePath,
userName: realUser.name,
userNo: realUser.idNumber
}).then(res => {
if (res.code == 200) {
uploadId()
}
}).catch(e => {
flag.value = Date.now()
})
},
fail: () => {
console.log('fail');
}
});
}
watch(flag, val => {
if (time.value >= 10) {
uni.showToast({
title: '人脸识别失败,请重试',
icon: 'error'
})
photoStatus(3)
time.value = 0
} else {
takePhoto()
}
})
const uploadId = () => {
proxy.$api.user.updateUser({
userName: realUser.name,
userNo: realUser.idNumber,
editType: 1,
id: uni.getStorageSync('id')
}).then(res => {
if (res.code == 200) {
uni.setStorageSync('idCard', 1)
uni.navigateTo({
url: './userInfo'
})
}
}).catch(e => {
})
}
/**
* 摄像头在非正常终止时触发,如退出后台等情况
*/
const stop = (e) => {
photoStatus(3)
}
/**
* 用户不允许使用摄像头时触发
*/
const error = (e) => {
console.log(3);
photoStatus()
}
const firstSuccess = () => {
uni.showLoading({
title: '初始化...'
})
photoStatus()
if (!ctx.value) {
ctx.value = uni.createCameraContext();
}
setTimeout(() => {
uni.hideLoading()
takePhoto()
}, 500)
}
const firstFail = () => {
photoStatus(-1)
}
onLoad((options) => {
realUser.name = options.name
realUser.idNumber = options.idNumber
})
</script>
<style lang="scss" scoped>
.face-detection {
background-color: #F3F3F3;
height: 100vh;
box-sizing: border-box;
padding: 30rpx;
position: relative;
.live-father {
width: 600rpx;
height: 600rpx;
border-radius: 50%;
margin: 100rpx auto;
.camera-box {
width: 100%;
height: 100%;
border-radius: 50%;
position: relative;
background-image: linear-gradient(to right, #acb6e5, #86fde8);
.camera-tip {
text-align: center;
line-height: 600rpx;
font-size: 70rpx;
font-weight: bold;
color: #fff;
.controls-play{
width: 390rpx;
height: 480rpx;
position: absolute;
top: 50%;
left: 50%;
z-index: 99;
transform: translate(-50%, -50%);
}
}
}
}
.bottom {
margin: 60rpx auto 0;
width: 690rpx;
height: 98rpx;
background-color: #CA2915;
border-radius: 16rpx;
font-size: 34rpx;
font-weight: 400;
color: #FFFFFF;
line-height: 98rpx;
text-align: center;
}
}
</style>