美文网首页
小程序人脸打卡开发

小程序人脸打卡开发

作者: Biao_349d | 来源:发表于2022-07-27 21:13 被阅读0次

最近做了一个小程序人脸识别的功能,主要就是前端做人脸检测, 后端调用人脸识别接口, 具体代码如下

// face-camera/index.wxml
<view class='camera'>
      <camera device-position="front" flash="off" binderror="error" style="width: 100%; height: 100%;" frame-size="small">
      </camera>
      <view class="tips" wx:if="{{!!tipsText}}">
        <view class="text">{{tipsText}}</view>
      </view>
  </view>

face-camera/index.wxss

/* pages/jobs/moving-clock/sign/comp/face-camera/index.wxss */

.camera{
  /* width: 480rpx;
  height: 480rpx; */
  width: 29.56vh;
  height: 29.56vh;
  border-radius: 50%;
  overflow: hidden;
  position: relative;
  z-index: 2;
}
.tips{
  position: absolute;
  bottom: 0;
  height: 96rpx;
  width: 100%;
  background-color: rgba(0, 0, 0, 0.6);
}
.tips .text{
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 24rpx;
  color: #fff;
  text-align: center;
  height: 100%;
  width: 100%;
  font-weight: 400;
}

face-camera/index.js

// pages/jobs/moving-clock/sign/comp/face-camera/index.js
Component({
  /**
   * 组件的属性列表
   */
  properties: {
    outTime: {
      type: Number,
      value: 15000
    },
    takePhotoIntervalTime: {
      type: Number,
      value: 1000
    },
    starting: {
      type: Boolean,
      value: false
    }
  },

  /**
   * 组件的初始数据
   */
  data: {
    ctx: null,
    tipsText: '',
    listener: null,
    startTime: 0
  },
  setTimeId: null,
  created() {
    const ctx = wx.createCameraContext();
    console.log('createCameraContext');
    wx.initFaceDetect({
      complete: (err) => {
        console.log('initFaceDetect', err);
      }
    });
    this.setData({
      ctx
    })
    this.handleOnCameraFrame((frame) => {
      if (this.data.starting) {
        console.log('frame', frame);
        this.handleWatchFaceData(frame);
      }
    });
  },
  lifetimes: {
    attached: function() {
      // 在组件实例进入页面节点树时执行
    },
    detached: function() {
      // 在组件实例被从页面节点树移除时执行
      wx.stopFaceDetect();
      let listener = this.data.listener;
      listener.stop();
    },
  },
  detached: function() {
    // 在组件实例被从页面节点树移除时执行
    wx.stopFaceDetect();
    let listener = this.data.listener;
    listener.stop();
  },

  /**
   * 组件的方法列表
   */
  methods: {
    handleOnCameraFrame(callback) {
      const that = this;
      const context = that.data.ctx;
      let listener = that.data.listener;
      let startTime = new Date().getTime();
      listener = context.onCameraFrame((frame) => {
        // console.log('frame', frame);
        const curTime = new Date().getTime()
        if (curTime - startTime >= 1000) {
          startTime = new Date().getTime();
          callback && callback(frame);
        }
      })
      listener.start({
        success: (res) => {
          console.log('listener.start', res);
        },
        fail: (err) => {
          console.log('listener.fail', err);
        }
      })
      this.setData({
        listener
      })
    },
    handleWatchFaceData(frame) {
      const that = this;
      let tipsText = '';
      wx.faceDetect({
        frameBuffer: frame.data,
        width:  frame.width,
        height: frame.height,
        enablePoint: true,
        enableConf: true,
        enableAngle: true,
        success: (faceData) => {
          console.log('faceDetect', faceData);
          let face = faceData

          if(faceData.x == -1 || faceData.y == -1) {
            tipsText = '检测不到人脸'
          }
          if(faceData.faceInfo && faceData.faceInfo.length > 1) {
            tipsText = '请保证只有一人做认证'
          } else {
            if(face.angleArray && (face.angleArray.pitch >= 0.3 || face.angleArray.roll >= 0.3 || face.angleArray.yaw >= 0.3)) {
              tipsText = '请平视摄像头'
            } else if(face.confArray && (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)) {
              tipsText = '请勿遮挡五官'
            } else {
              tipsText = '请不要移动!'
              // 这里可以写自己的逻辑了
              if (that.data.startTime === 0) {
                that.takePhoto((res) => {
                  console.log('takePhoto', res);
                  that.setData({
                    startTime: new Date().getTime()
                  })
                  // 为了增强体验,不会造成闪拍,延迟三秒;
                  setTimeout(() => {
                    that.setData({
                      startTime: 0
                    })
                    that.triggerEvent('takePhoto', res);
                  }, 3000)
                })
              }
            }
          }
          that.setData({
            tipsText
          })
        },
        fail:function  (err)  {
          console.log(err)
          if(err.x == -1 || err.y == -1) {
            tipsText = '检测中,请面向摄像头'
          } else {
            tipsText = '网络错误,请退出页面重试'
          }
          // 这里可以写自己的逻辑了
          if (that.data.startTime === 0) {
              that.setData({
                startTime: new Date().getTime()
              })
              // 为了增强体验,不会造成闪拍,延迟5秒;
              setTimeout(() => {
                that.takePhoto((res) => {
                  console.log('takePhoto', res);
                  that.setData({
                    startTime: 0
                  })
                  that.triggerEvent('takePhoto', res);
                })
              }, 4000)
          }
          that.setData({
            tipsText
          })
        }
      })
    },
    handleStartDetect() {
    },
    handleVideo(callback) {
      // let that = this;
      const CameraContext = this.data.ctx;
      CameraContext.startRecord({
        timeout: 15,
        selfieMirror: true,
        success: (res) => {
          console.log('startRecord', res);
          callback && callback(res);
        },
        timeoutCallback: (e) => {
          const tempVideoPath = e.tempVideoPath;
          console.log('timeoutCallback', e);
        },
        complete: (e) => {
          console.log('complete', e);
        }
      })
    },

    // 拍照
    takePhoto(callback) {
        let that = this;
        const ctx = this.data.ctx;
        ctx.takePhoto({
            quality: 'high',
            success: (res) => {
                callback && callback(res);
            },
            fail: function (res) {
                wx.showToast({
                    title: '拍照错误',
                    icon: 'none',
                    duration: 2000
                });
            }
        })
    },
    error(e) {
        wx.$fn.showModal({
          title: '提示',
          context: '请允许小程序使用摄像头',
          confirmText: '知道了',
          mask: true,
          confirm: function() {
            wx.switchTab({
              url: '/pages/jobs/jobs',
            })
          },
        }, this);
    },
    getAuthInfo(callback) {
      let systemScopeMsgList = [];
      let obj = {
        cameraAuthorized: true,
        camera: true
      }
      // 可以通过 wx.getSetting 先查询一下用户是否授权了 "scope.record" 这个 scope
      wx.getSetting({
        success(settingRes) {
          console.log('settingRes', settingRes);
          if (settingRes.authSetting['scope.camera'] !== true) {
            systemScopeMsgList.push('摄像头未授权')
            obj.camera = false
          }
          wx.getSystemInfo({
            success (res) {
              console.log('getSystemInfo', res);
              const cameraAuthorized = res.cameraAuthorized; // 允许微信使用摄像头的开关
  
              if (!cameraAuthorized) {
                obj.cameraAuthorized = false
                systemScopeMsgList.push('微信使用摄像头的开关未开启');
              }
              // if (!res.model) {
              //   obj.model = false
              //   systemScopeMsgList.push('该机器为新机型,检测信息可能有误,如使用出现问题,请手动摄像头授权是否开启');
              // }
              obj.brand = res.brand;
              callback && callback(systemScopeMsgList, obj)
            }
          })
        }
      })
    }
  },
})

index.json
{
  "component": true,
  "usingComponents": {}
}


下面是使用方式

data: {
    isFaceStart: true,
isLoading: false,
serverUrl : 'http://xxx/xx/xx',
tabActiveId: 1
},
  curTimeTimeId: null,
  faceTimeId: null,

        <face-camera id="faceCameraId" starting="{{isFaceStart}}" bind:takePhoto="handleTakePhoto"></face-camera>



    handleTakePhoto(e) {
      const that = this;
      const res = e.detail || {};
      const { tempImagePath } = res;
      if (this.data.isLoading) {
        return false;
      }
      this.setData({
        isFaceStart: false,
        cameraFaceTime: 0,
        isLoading: true
      });
      clearInterval(this.faceTimeId);
      wx.showLoading()
      this.uploadMedia(this.data.serverUrl + "/api/xcxoperator/face/validate", tempImagePath).then(res => {
        console.log('sign-res', res);
        let msg = res.msg || (res.code === '200' ? '验证成功' : '验证失败');
        if (res.data && res.data.msg) {
          msg = res.data.msg;
        }
        if (res && res.code === '200') {
          wx.showModal({
            title: '打卡成功',
            context: msg,
            confirmText: '知道了',
            mask: true,
            confirm: function() {
              that.setData({
                isLoading: false
              })
              wx.switchTab({
                url: '/pages/home/index',
              })
            },
          }, that);
        } else {
          wx.showModal({
            title: '打卡失败',
            context: msg,
            confirmText: '知道了',
            mask: true,
            confirm: function() {
              // 防重复提交
              that.setData({
                  isLoading: false
                });
            },
          }, that);
        }
      })
    },
  
    uploadMedia: function (serverUrl, url) {
      return new Promise((resolve, reject) => {
        wx.uploadFile({
          url: serverUrl,
          name: 'file',
          header: {
            Cookie: wx.getStorageSync('Cookie')
          },
          formData: {
            'faceType': +this.data.tabActiveId
          },
          filePath: url,
          success: function (res) {
            console.log(res);
            const data = JSON.parse(res.data);
            wx.hideLoading()
            resolve(data);
          },
          fail: function () {
            wx.hideLoading()
            resolve({})
          }
        })
      })
    },

相关文章

  • 基于百度AI接口的微信小程序-人脸搜索

    本文主要介绍基于百度云人脸识别接口实现微信小程序人脸搜索 开发前的准备: 参考文档:https://develop...

  • 潍坊小程序开发

    潍坊小程序开发潍坊小程序开发潍坊小程序开发潍坊小程序开发潍坊小程序开发潍坊小程序开发潍坊小程序开发潍坊小程序开发潍...

  • 潍坊商城小程序开发制作

    潍坊小程序开发潍坊小程序开发潍坊小程序开发潍坊小程序开发潍坊小程序开发潍坊小程序开发潍坊小程序开发潍坊小程序开发潍...

  • 潍坊商城小程序网站开发制作

    潍坊商城小程序开发制作潍坊商城小程序开发制作潍坊商城小程序开发制作潍坊商城小程序开发制作潍坊商城小程序开发制作潍坊...

  • 使用Java开发人脸融合(换军装等)并接入微信小程序

    详情移步开源中国查看。那里格式看的舒服 使用Java开发人脸融合(换军装等)并接入微信小程序

  • 小程序Cloud开发归纳

    小程序云开发 小程序·云开发是微信团队联合腾讯云推出的专业的小程序开发服务。开发者可以使用云开发快速开发小程序、小...

  • “Keep书写”系统说明

    一、开发此App的理由 主要对比流行的打卡App,例如微信小程序,小打卡 是面对通用打卡; 有广告及多余的弹框; ...

  • 微信小程序开发系列六:微信框架API的调用

    微信小程序开发系列教程 微信小程序开发系列一:微信小程序的申请和开发环境的搭建 微信小程序开发系列二:微信小程序的...

  • 共享链小程序软件开发

    共享链小程序模式开发;共享链小程序软件源码开发;共享链小程序系统开发;共享链小程序系统模式。 共享链小程序商家返利...

  • 微信小程序的开发与原理

    微信小程序的开发与原理 1, 小程序与普通网⻚开发的区别 小程序的主要开发语言是 JavaScript ,小程序的...

网友评论

      本文标题:小程序人脸打卡开发

      本文链接:https://www.haomeiwen.com/subject/ycoxwrtx.html