javascript
复制代码
// pages/face/index.js
Page({
/**
* 页面的初始数据
*/
data() {
return {
isShow: false,
tipsText: '', // 错误文案提示
tempImg: '', // 本地图片路径
cameraEngine: null, // 相机引擎
devicePosition: false, // 摄像头朝向
isAuthCamera: true, // 是否拥有相机权限
isVerify: false,
translateY: -24,
timer: null,
isFlag: true,
origin: null,
base64: "",
personId: "",
isFlag2: true,
screenWidth: 375,
screenHeight: 640,
faceImage: '', //人脸图片
}
},
onShow: function () {
this.setData({
isVerify: false,
tipsText: "",
isFlag: true,
})
this.lineAnimation();
},
onLoad(options) {
this.initData();
},
onUnload() {
this.clearTimer();
},
onHide() {
this.clearTimer();
},
clearTimer() {
if (this.data.timer) {
clearInterval(this.data.timer);
this.setData({
timer: null,
})
}
this.setData({
isFlag: false,
})
},
// 初始化相机引擎
initData() {
// #ifdef MP-WEIXIN
// 1、初始化人脸识别
wx.initFaceDetect();
// 2、创建 camera 上下文 CameraContext 对象
this.setData({
cameraEngine: wx.createCameraContext(),
isShow: true,
})
// 3、获取 Camera 实时帧数据
const listener = this.data.cameraEngine.onCameraFrame((frame) => {
console.log(888888888, frame.data, frame.width, frame.height)
if (this.data.isVerify) return
//动态设置canvas的宽高,不设置会导致部分机型人脸不完整导致不能识别-----很重要!很重要!很重要!
if (this.data.isFlag2) {
this.setData({
isFlag2: false,
screenWidth: frame.width,
screenHeight: frame.height,
})
}
// 4、人脸识别,使用前需要通过 wx.initFaceDetect 进行一次初始化,推荐使用相机接口返回的帧数据
wx.faceDetect({
frameBuffer: frame.data,
width: frame.width,
height: frame.height,
enablePoint: true,
enableConf: true,
enableAngle: true,
enableMultiFace: true,
success: async (faceData) => {
console.log(1111, faceData)
let face = faceData.faceInfo[0]
if (face.x == -1 || face.y == -1) {
this.setData({
tipsText: '检测不到人'
})
}
if (faceData.faceInfo.length > 1) {
this.setData({
tipsText: '请保证只有一个人'
})
} else {
const {
pitch,
roll,
yaw
} = face.angleArray;
const standard = 0.5
if (Math.abs(pitch) >= standard || Math.abs(roll) >= standard ||
Math.abs(yaw) >= standard) {
this.setData({
tipsText: '请平视摄像头'
})
} else if (face.confArray.global <= 0.8 || face.confArray.leftEye <=
0.8 || face.confArray.mouth <= 0.8 || face.confArray.nose <= 0.8 ||
face.confArray.rightEye <= 0.8) {
this.setData({
tipsText: '请勿遮挡五官'
})
} else {
if (this.isVerify) return
//人脸位置校验
var centerWidth = 250;
var centerHeight = 250;
if (face.x > (frame.width - centerWidth) / 2 && face.x < (frame
.width - centerWidth) / 2 + centerWidth && face.y > (frame
.height - centerHeight) / 2 && face.y < (frame.height -
centerHeight) / 2 + centerHeight) {
this.setData({
tipsText: '校验中...',
isVerify: true
})
// 太快获取的人脸可能比较抽象,给用户一个准备时间
setTimeout(async () => {
let img = await this.changeDataToBase64(
frame);
this.setData({
base64: img
})
this.searchUserFace();
}, 300)
} else {
this.setData({
tipsText: '请将人脸对准中心位置'
})
}
}
}
},
fail: (err) => {
console.log(2222, err)
if (this.isVerify) return
if (err.x == -1 || err.y == -1) {
this.setData({
tipsText: '检测不到人'
})
} else {
this.setData({
tipsText: err.errMsg || '网络错误,请退出页面重试'
})
}
},
})
})
// 5、开始监听帧数据
listener.start()
this.setData({
listener: listener
})
// #endif
},
reverse() {
let a = this.data.devicePosition
this.setData({
devicePosition: !a
})
},
clickScanCode() {
// 只允许通过相机扫码
// #ifdef MP-WEIXIN
wx.scanCode({
onlyFromCamera: true,
success: (res) => {
var data = JSON.parse(res.result.replace(/\ufeff/g, ""));
}
});
// #endif
},
changeDataToBase64(frame) {
console.log(4444, frame)
return new Promise((resolve, reject) => {
var data = new Uint8Array(frame.data);
var clamped = new Uint8ClampedArray(data);
let that = this;
var width = this.data.screenWidth;
var height = frame.height * this.data.screenWidth / frame.width;
wx.canvasPutImageData({
canvasId: 'myCanvas',
x: 0,
y: 0,
width: frame.width,
height: frame.height,
data: clamped,
success(res) { // 转换临时文件
console.log(5555, res)
wx.canvasToTempFilePath({
x: 0,
y: 0,
width: width,
height: height,
canvasId: 'myCanvas',
fileType: 'jpg',
destWidth: width,
destHeight: height, // 精度修改
quality: 0.5,
success(res) {
console.log(666, res)
// 临时文件转base64
wx.getFileSystemManager().readFile({
filePath: res.tempFilePath, //选择图片返回的相对路径
encoding: 'base64', //编码格式
success: res => {
console.log(7777, res)
// 保存base64
resolve(res.data);
}
})
},
fail(res) {
console.log(8888, res)
reject(false);
}
});
},
fail(error) {
console.log(error);
}
})
})
},
searchUserFace() {
// 1.人脸识别错误 把isVerify设置为true继续识别
// 2.人脸识别成功,做对应的逻辑
console.log(333, this.data.base64)
this.setData({
faceImage: 'data:image/jpeg;base64,' + this.data.base64,
tipsText: '校验成功'
})
wx.stopFaceDetect(); //关闭人脸识别
this.data.listener.stop(); //关闭camera摄像头监听
return
var params = {
faceImage: this.data.base64,
}
searchFaces(params).then(res => {
console.log(444, res)
if (res.code == 200) {
wx.stopFaceDetect(); //关闭人脸识别
this.data.listener.stop(); //关闭camera摄像头监听
this.clickPushDetail(res.data.personCode);
this.setData({
tipsText: '校验成功'
})
}
}).catch(error => {
setTimeout(() => {
this.setData({
isVerify: 'false'
})
}, 500)
this.setData({
tipsText: '暂未查找到相关人员'
})
})
},
clickPushDetail() {
// 跳转到其他页面
},
lineAnimation() {
if (this.timer) return
this.setData({
timer: setInterval(() => {
this.setData({
translateY: this.data.translateY + 8
})
if (this.data.translateY >= 460) {
this.setData({
translateY: 10
})
}
}, 40)
})
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh() {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom() {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage() {
}
})