- wx.createVKSession()
使用人脸检测,发现on('updateAnchors',()=>{})没出发,启动事件返回null是成功的。是缺少api和模板camera组件做绑定吗。 <template> <view class="face-bio-assay-container"> <text>{{ isSuccess ? '' : tipsText}}</text> <view class="camera-box"> <!-- VKSession会自动管理摄像头,不需要额外的camera组件 --> </view> </view> </template> <script> // 人脸检测 /** * @event {Function} photoChange 拍照完成事件 * @event {Function} detectFailed 人脸检测失败 * @event {Function} detectOver 人脸检测结束 * @method {Function} initData 初始化人脸检测 */ export default { name: 'face-detect', data() { return { device: 'front', show: false, showCamera: true, faceImg: '', tipsText: '请将脸部移入框内', isSuccess: false, //是否检测完成 face: {}, context: "", tipsTextCss: "tipsTextCss", vkSession: null, // 将vkSession作为组件数据的一部分 isVKSessionStarted: false, detectionStep: 0, // 0: 正脸检测, 1: 点头检测, 2: 摇头检测, 3: 拍照 initialPitch: 0, initialYaw: 0, nodDetected: false, shakeDetected: false, detectionStartTime: 0, useLegacyAPI: false // 是否使用旧API } }, props: { hasSwitch: { type: Boolean, default: false }, isDev: { type: Boolean, default: false }, }, destroyed() { this.cleanupVKSession() }, methods: { deviceQH() { if (!this.hasSwitch) { return } this.device = this.device == 'back' ? 'front' : 'back'; }, onCameraFrame() { // 使用新的VKSession API替代原有的faceDetect console.log('onCameraFrame') this.initVKSession() }, // 初始化VKSession initVKSession() { // 检查是否支持VKSession if (!wx.createVKSession) { console.log('不支持...') this.tipsText = "当前微信版本不支持,请升级微信" this.cameraError() return } // 创建VK会话,尝试使用v1版本以获得更好的兼容性 this.vkSession = wx.createVKSession({ version: 'v2', track: { face: { mode: 1 // 1表示检测最大的人脸 } }, fail: (res) => { console.error('VKSession创建失败', res) this.tipsText = "人脸检测初始化失败: " + (res.errMsg || JSON.stringify(res)) this.cameraError() }, success: (res) => { console.log('VKSession创建成功', res) } }) console.log(this.vkSession,'vkSessionvkSession') // 监听锚点更新(人脸检测) this.vkSession.on('updateAnchors', (anchors) => { console.log('VKSession更新锚点', anchors) if (!this.isVKSessionStarted) { this.isVKSessionStarted = true this.detectionStep = 0 this.tipsText = "请保持正脸面对摄像头" this.detectionStartTime = Date.now() } // 检测超时 if (Date.now() - this.detectionStartTime > 30000) { // 30秒超时 this.tipsText = "检测超时,请重新开始" this.cameraError() return } if (anchors && anchors.length > 0) { const anchor = anchors[0] // 获取最大的人脸 // 活体检测(使用锚点的稳定度作为判断) if (anchor.score > 0.8) { // 稳定度阈值 // 从anchor中提取角度信息 const angles = anchor.angle || [0, 0, 0] const pitch = angles[0] // 俯仰角 const yaw = angles[1] // 偏航角 const roll = angles[2] // 翻滚角 // 构造类似face的对象传递给处理函数 const faceData = { pitch: pitch, yaw: yaw, roll: roll } this.processFaceDetection(faceData) } else { this.tipsText = "请确保是真实人脸" } } else { this.tipsText = "请将脸部移入框内" } }) // 监听锚点移除 this.vkSession.on('removeAnchors', () => { console.log('人脸离开检测区域') this.tipsText = "请将脸部移入框内" }) // 监听错误 this.vkSession.on('error', (error) => { console.error('VKSession错误', error) this.tipsText = "人脸检测出错: " + (error.errMsg || JSON.stringify(error)) this.cameraError() }) // 启动会话 this.vkSession.start((code)=>{ console.log('VKSession启动',code) }) }, // 处理人脸检测逻辑 processFaceDetection(face) { console.log(face,'facefaceface') const pitch = face.pitch const yaw = face.yaw const roll = face.roll switch (this.detectionStep) { case 0: // 正脸检测 if (Math.abs(pitch) < 0.2 && Math.abs(yaw) < 0.2 && Math.abs(roll) < 0.2) { this.initialPitch = pitch this.initialYaw = yaw this.detectionStep = 1 this.tipsText = "请缓慢点头" } else { this.tipsText = "请保持正脸面对摄像头" } break case 1: // 点头检测 // 检测点头动作(pitch变化) if (pitch - this.initialPitch < -0.3) { // 向下点头 this.nodDetected = true this.tipsText = "请缓慢摇头" this.detectionStep = 2 } else { this.tipsText = "请缓慢点头" } break case 2: // 摇头检测 // 检测摇头动作(yaw变化) if (Math.abs(yaw - this.initialYaw) > 0.4) { // 左右摇头 this.shakeDetected = true this.tipsText = "检测完成,正在拍照" this.detectionStep = 3 // 延迟拍照,给用户一个准备时间 setTimeout(() => { this.takePhotoWithVK() }, 1000) } else { this.tipsText = "请缓慢摇头" } break } }, // 使用VKSession拍照 takePhotoWithVK() { if (this.vkSession && this.isVKSessionStarted) { // 停止VKSession this.cleanupVKSession() // 使用相机上下文拍照 this.context = this.context || uni.createCameraContext() this.context.takePhoto({ quality: 'high', success: (res) => { this.$emit('photoChange', res.tempImagePath) }, fail: (e) => { console.log(e, 'fail') this.tipsText = "拍照失败,请重试" this.cameraError() } }) } }, // 核验失败 cameraError(e) { console.error('相机错误', e) this.cleanupVKSession() this.hideModal() this.$emit('detectFailed') }, close() { clearTimeout(this.t) this.hideModal() this.$emit('detectFailed') }, // 关闭 hideModal() { this.cleanupVKSession() this.show = false this.tipsText = '请将脸部移入框内' this.face = {} this.isSuccess = false this.detectionStep = 0 this.nodDetected = false this.shakeDetected = false this.useLegacyAPI = false }, // 拍照 takePhoto() { // 使用VKSession时,拍照由takePhotoWithVK处理 // 保留此方法以兼容其他调用方式 this.context.takePhoto({ quality: 'high', success: (res) => { // this.showCamera = false // this.faceImg = res.tempImagePath this.$emit('photoChange', res.tempImagePath) }, fail: (e) => { console.log(e, 'fail') }, complete: (e) => { console.log(e, 'complete') } }); }, // 检测完成 detectOver() { this.isSuccess = true let t = setTimeout(() => { this.hideModal() clearTimeout(t) this.$emit('detectOver') }, 3000); }, initData() { uni.getSetting({ success: (res) => { if (res.authSetting['scope.camera'] === true) { this.onCameraFrame() } else if (res.authSetting['scope.camera'] === false) { this.showCamera = false this.getCameraAuth() } else { this.onCameraFrame() } }, fail: (err) => { console.error('获取相机设置失败', err) // 即使获取设置失败,也尝试启动摄像头 this.onCameraFrame() } }) }, getCameraAuth() { uni.showModal({ title: '温馨提示', content: '需要获取您摄像头权限才能更好的为您服务!是否授权摄像头权限?', confirmText: '授权', confirmColor: '#f94218', success: (res) => { if (res.confirm) { // 选择弹框内授权 uni.openSetting({ success: (res) => { if (res.authSetting[ 'scope.camera' ]) { this.showCamera = true this.$nextTick(() => { this.onCameraFrame() }) } else { this.tipsText = "您未授权摄像头权限" this.cameraError() } }, fail: (err) => { console.error('打开设置失败', err) this.tipsText = "授权失败" this.cameraError() } }) } else if (res.cancel) { this.tipsText = "您未授权摄像头权限" this.cameraError() } }, fail: (err) => { console.error('显示模态框失败', err) this.tipsText = "授权请求失败" this.cameraError() } }) }, showData(faceData) { this.$emit("showData", faceData) if (this.isDev) { let face = faceData.faceInfo[0].angleArray this.face = face } }, // 清理VKSession资源 cleanupVKSession() { if (this.vkSession) { try { if (this.isVKSessionStarted) { this.vkSession.stop() } this.vkSession.destroy() } catch (e) { console.error('清理VKSession资源时出错', e) } this.vkSession = null this.isVKSessionStarted = false } }, // 初始化人脸检测 faceDetect() { this.show = true } } } </script> <style lang="scss" scoped> .face-bio-assay-container { width: 100%; height: 717rpx; display: flex; flex-direction: column; align-items: center; justify-content: flex-end; >text { width: fit-content; font-weight: bold; font-size: 40rpx; color: #000000; line-height: 48rpx; white-space: nowrap; margin-bottom: 54rpx; } .camera-box { width: 570rpx; height: 570rpx; background: #eeeeee; border-radius: 50%; border: 6rpx solid #5c1b73; box-sizing: border-box; overflow: hidden; -webkit-backface-visibility: hidden; -webkit-transform: translate3d(0, 0, 0); } } </style>
星期三 17:43 - 企业微信小程序模式下,笔记本无法看到模拟器底部的页面路径这一栏,大屏才可以看到
企业微信小程序模式下,笔记本无法看到模拟器底部的页面路径这一栏,大屏才可以看到 [图片] [图片]
01-16 - 手机号实时验证组件的代码示例
https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/getRealtimePhoneNumber.html 手机号实时验证组件的代码示例 回调参数错了 [图片]
2023-07-04