微信小程序人脸识别获取照片,并解决相机拍照在ios上有声音问题

日常记录碰到的问题:
我目前是人脸识别需要获取照片,按照当前需求所写
首先在微信小程序中拍照会使用到camera组件,该组件需要用户授权,拒绝授权的情况以后可能会补充,目前展示仅仅为允许授权的情况。
在这里插入图片描述

组件中设置的值根据需求查看官网进行修改,官网地址:微信小程序camera组件
page.wxml:
这里的windowHeight是我获取的手机高度,因为原生组件的层级太高,我将画布放在的页面外面并在page.json中给页面"disableScroll": true设置了不可拖动的参数

 <camera wx:if="{
     
     {!src}}" class="camera" device-position="front" frame-size="small" flash="off" binderror="error" style="">
  </camera>
  <canvas class="canvas" style="height:{
       
       {
       
       windowHeight}}px;margin-top:{
       
       {
       
       windowHeight}}px;" canvas-id="firstCanvas"></canvas>

page.wxss:

.camera {
    
    
  width: 400rpx;
  height: 400rpx;
  border-radius: 50%;
  z-index: 1;
}

.canvas {
    
    
  width: 100%;
  box-sizing: border-box;
  z-index: 0;
}

最重要的是page.js文件,这里用到wx.createCameraContext()创建系统相机上下文对象,onCameraFrame获取实时帧数据,wx.canvasPutImageData将像素数据绘制到画布,wx.canvasToTempFilePath保存图片等api方法

这里解释一下为什么会用到画布:
首先采用takePhoto方法进行拍照,因为ios系统设置中有防止偷拍的设定,所以即使在静音的情况下,ios拍照也会发出咔嚓的声音,而官方文档中并没有能控制这个情况的参数,所以要采用onCameraFrame获取相机实时帧,得到的数据是未经过处理的类似于二进制的数据(个人理解),在使用画布,先用wx.canvasPutImageData将得到的图像数据画出来,在使用wx.canvasToTempFilePath方法将画布上的照片保存下来转为base64格式传给后台即可

page.js:

const app = getApp()
let listener = ''
Page({
    
    

  /**
   * 页面的初始数据
   */
  data: {
    
    
    src: null,
    status: {
    
    
      record: false,
      camera: 'front'
    },
    detectLiveFace: null,
    Bullet_frame: false,
    serintervalTime: null,
    /
    device: true,
    speedMaxCount: 30,//用来限制实时帧获取时间,减少后台请求与UI压力
    /
    windowHeight:0,//页面高度
  },
  onShow: function () {
    
    
    let that = this
    const ctx = wx.createCameraContext()
    that.startTacking()//调用获取相机实时帧方法
  },
  //调用获取相机实时帧方法
  startTacking() {
    
    
    var _that = this;
    var count = 0;
    const context = wx.createCameraContext();
    if (!context.onCameraFrame) {
    
    
      var message = '基础库 2.7.0 开始支持".';
      wx.showToast({
    
    
        title: message,
        icon: 'none'
      });
      return;
    }
    listener = context.onCameraFrame(function (res) {
    
     // 每秒60帧,这里控制每0.5获取一次图片 
      // console.log('实时像素帧', res)
      if (count < _that.data.speedMaxCount) {
    
    
        count++;
        // console.log('count count count', count)
        return;
      }
      count = 0;
      console.log('当等于30时')
      // onCameraFrame 获取的是未经过编码的原始 RGBA 格式的图像数据,接下来转为图片  
      _that.jschangeDataToBase64(res)
    });
    // start
    listener.start();
  },
  // 将实时帧在canvas上画出来,并保存的到图片路径
jschangeDataToBase64(frame) {
    
    
    var data = new Uint8Array(frame.data);
    var clamped = new Uint8ClampedArray(data);
    let that = this
    // console.log('clamped clamped', clamped)
    var contex = wx.createCanvasContext('firstCanvas')
    wx.canvasPutImageData({
    
    
      canvasId: 'firstCanvas',
      x: 0,
      y: 0,
      width: frame.width,
      height: frame.height,
      data: clamped,
      success(res) {
    
    
        // 转换临时文件
        // console.log('转换临时文件', res)
        wx.canvasToTempFilePath({
    
    
          x: 0,
          y: 0,
          width: frame.width,
          height: frame.height,
          canvasId: 'firstCanvas',
          fileType: 'png',
          destWidth: frame.width,
          destHeight: frame.height,
          // 精度修改  
          quality: 0.8,
          success(res) {
    
    
            // 临时文件转base64
            let oddurl = res.tempFilePath
            wx.getFileSystemManager().readFile({
    
    
              filePath: res.tempFilePath,
              //选择图片返回的相对路径  
              encoding: 'base64',
              //编码格式  
              success: res => {
    
    
                // 保存base64
                let base64 = res.data;
                console.log('转化完成',res)
                // 拿到数据后的其他操作  调用请求接口方法,将得到的数据发送到后台  
                that.detectLiveFace(base64, oddurl)
                
              }
            })
          },
          fail(res) {
    
    
            console.log(res)
            wx.showToast({
    
    
              title: '图片生成失败,重新检测',
              icon: 'none',
              duration: 1000
            }) // 测试的时候发现安卓机型,转为临时文件失败,这里从新获取帧数据,再转码就能成功
          }
        }, that)
      },
      fail(res) {
    
    
        console.log('调用失败', res)
      }
    })
  },
    // 结束相机实时帧
  stopTacking() {
    
    
    if (listener) {
    
    
      listener.stop();
    }
  },
    // 开始相机实时帧
      startcamera:function(){
    
    
    if(listener){
    
    
      listener.start()
    }
  },
 detectLiveFace:function(url, oddurl){
    
    
   let that = this
    that.stopTacking()
    console.log('得到的base64图像路径',url,'之前的路径',oddurl)
    //请求接口
  },
   
  
 })

猜你喜欢

转载自blog.csdn.net/weixin_50147372/article/details/113941124