vue+tracking.js H5人脸识别-拍照转base64

npm install tracking
安装完直接复制以下代码到页面使用即可

<template>
  <div id="seePerson">
    <div v-show="showContainer" class="face-capture" id="face-capture">
      <p class="tip">请保持人像在取景框内</p>
      <video
        id="video"
        :width="vwidth"
        :height="vheight"
        playsinline
        webkit-playsinline
      ></video>
      <canvas id="refCanvas" :width="cwidth" :height="cheight"></canvas>
      <!-- <img class="img-cover" :src="getImageUrl('yuan')" alt="" /> -->
      <!-- <div class="yuan"></div> -->
      <p class="contentp">{{ scanTip }}</p>
    </div>
    <div v-if="!showContainer" class="img-face">
      <img class="imgurl" :src="imgUrl" />
    </div>
    <div class="face-card">
      <van-form @submit="onSubmit">
        <van-field name="fileList" label="身份证上传">
          <template #input>
            <van-uploader v-model="fileList" :after-read="afterRead" />
          </template>
        </van-field>
        <van-field
          v-model="username"
          name="username"
          label="法人信息"
          placeholder="法人信息"
          :rules="[{ required: true, message: '请填写法人信息' }]"
        />
        <van-field
          v-model="password"
          type="password"
          name="password"
          label="身份证号码"
          placeholder="身份证号码"
          :rules="[{ required: true, message: '请填写身份证号码' }]"
        />
        <div style="margin: 16px">
          <van-button round block type="info" native-type="submit"
            >提交</van-button
          >
        </div>
      </van-form>
    </div>
  </div>
</template>
<script>
require("tracking/build/tracking-min.js");
require("tracking/build/data/face-min.js");
require("tracking/build/data/mouth-min.js");
require("tracking/examples/assets/stats.min.js");
export default {
  data() {
    return {
      username: "",
      password: "",
      fileList: [],
      screenSize: {
        width: window.screen.width,
        height: window.screen.height,
      },
      URL: null,
      streamIns: null, // 视频流
      showContainer: true, // 显示
      tracker: null,
      tipFlag: false, // 提示用户已经检测到
      flag: false, // 判断是否已经拍照
      context: null, // canvas上下文
      profile: [], // 轮廓
      removePhotoID: null, // 停止转换图片
      scanTip: "人脸识别中...", // 提示文字
      imgUrl: "",
      canvas: null,
      trackertask: null,
      vwidth: "400",
      vheight: "400",
      cwidth: "400",
      cheight: "400",
      userInfo: {},
      orderData: {},
    };
  },
  created() {},
  mounted() {
    this.setVideoConfig();
  },
  methods: {
    // 调用摄像头
    setVideoConfig() {
      const scale = this.screenSize.width / 375;
      this.vwidth = 400 * scale;
      this.vheight = 400 * scale;
      this.cwidth = 400 * scale;
      this.cheight = 400 * scale;
      this.playVideo();
    },
    getUserMedia(constrains) {
      if (navigator.mediaDevices.getUserMedia) {
        //最新标准API
        navigator.mediaDevices
          .getUserMedia(constrains)
          .then((res) => {
            this.handleSuccess(res);
          })
          .catch((err) => {
            this.handleError(err);
          });
      } else if (navigator.webkitGetUserMedia) {
        //webkit内核浏览器
        navigator
          .webkitGetUserMedia(constrains)
          .then((res) => {
            this.handleSuccess(res);
          })
          .catch((err) => {
            this.handleError(err);
          });
      } else if (navigator.mozGetUserMedia) {
        //Firefox浏览器
        navagator
          .mozGetUserMedia(constrains)
          .then((res) => {
            this.handleSuccess(res);
          })
          .catch((err) => {
            this.handleError(err);
          });
      } else if (navigator.getUserMedia) {
        //旧版API
        navigator
          .getUserMedia(constrains)
          .then((res) => {
            this.handleSuccess(res);
          })
          .catch((err) => {
            this.handleError(err);
          });
      } else {
        this.scanTip = "你的浏览器不支持访问用户媒体设备";
      }
    },
    close() {
      this.flag = false;
      this.tipFlag = false;
      this.showContainer = false;
      this.context = null;
      this.scanTip = "人脸识别中...";
      clearTimeout(this.removePhotoID);
      if (this.streamIns) {
        this.streamIns.enabled = false;
        this.streamIns.getTracks()[0].stop();
        this.streamIns.getVideoTracks()[0].stop();
      }
      this.streamIns = null;
      this.trackertask.stop();
      this.tracker = null;
    },
    // 拍照
    tackPhoto() {
      // 在画布上面绘制拍到的照片
      this.context.drawImage(
        document.getElementById("video"),
        0,
        0,
        this.vwidth,
        this.vwidth
      );
      // 保存为base64格式
      this.imgUrl = this.saveAsPNG(document.getElementById("refCanvas"));
      console.log("此处调取接口对比img", this.imgUrl);
      //判断图片大小
      this.imgSize();
      /**
       * @function 这里可以调用后端接口将图片上传比对,然后调用close结束进程
       */
      this.close();
    },

    imgSize() {
      if (this.imgUrl) {
        // 获取base64图片byte大小
        const equalIndex = this.imgUrl.indexOf("="); // 获取=号下标
        let size;
        if (equalIndex > 0) {
          const str = this.imgUrl.substring(0, equalIndex); // 去除=号
          const strLength = str.length;
          const fileLength = strLength - (strLength / 8) * 2; // 真实的图片byte大小
          size = Math.floor(fileLength / 1024); // 向下取整
          console.log("size", size + "KB");
        } else {
          const strLength = this.imgUrl.length;
          const fileLength = strLength - (strLength / 8) * 2;
          size = Math.floor(fileLength / 1024); // 向下取整
          console.log("base64:size", size + "KB");
        }
        if (size > 1024) {
          // 图片超过1M 按比例压缩
          this.imgUrl = document
            .getElementById("refCanvas")
            .toDataURL("image/png", 1024 / size);
        }
      }
    },
    // Base64转文件
    getBlobBydataURI(dataURI, type) {
      const binary = window.atob(dataURI.split(",")[1]);
      const array = [];
      for (let i = 0; i < binary.length; i++) {
        array.push(binary.charCodeAt(i));
      }
      return new Blob([new Uint8Array(array)], {
        type: type,
      });
    },
    // 保存为png,base64格式图片
    saveAsPNG(c) {
      return c.toDataURL("image/png", 0.4);
    },
     人脸捕捉 设置各种参数 实例化人脸捕捉实例对象,注意canvas上面的动画效果。

    initTracker() {
      this.context = document.getElementById("refCanvas").getContext("2d"); // 画布
      this.canvas = document.getElementById("refCanvas");
      this.tracker = new window.tracking.ObjectTracker("face"); // tracker实例
      this.tracker.setInitialScale(4);
      this.tracker.setStepSize(2); // 设置步长
      this.tracker.setEdgesDensity(0.1);
      try {
        this.trackertask = window.tracking.track("#video", this.tracker); // 开始追踪
      } catch (e) {
        this.scanTip = "访问用户媒体失败,请重试";
      }
      //开始捕捉方法 一直不停的检测人脸直到检测到人脸
      this.tracker.on("track", (e) => {
        //画布描绘之前清空画布
        this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
        if (e.data.length === 0) {
          this.scanTip = "未检测到人脸";
        } else {
          e.data.forEach((rect) => {
            //设置canvas 方框的颜色大小
            this.context.strokeStyle = "#42e365";
            this.context.lineWidth = 2;
            this.context.strokeRect(rect.x, rect.y, rect.width, rect.height);
          });
          if (!this.tipFlag) {
            this.scanTip = "检测成功,正在拍照,请保持不动2秒";
          }
          // 1.5秒后拍照,仅拍一次 给用户一个准备时间
          // falg 限制一直捕捉人脸,只要拍照之后就停止检测
          if (!this.flag) {
            this.scanTip = "拍照中...";
            this.flag = true;
            this.removePhotoID = setTimeout(() => {
              this.tackPhoto();
              document.getElementById("video").pause();
              this.tipFlag = true;
            }, 2000);
          }
        }
      });
    },
    // 成功回调
    handleSuccess(stream) {
      this.streamIns = stream;
      const video = document.getElementById("video");
      // webkit内核浏览器
      this.URL = window.URL || window.webkitURL;
      if ("srcObject" in video) {
        video.srcObject = stream;
      } else {
        video.src = this.URL.createObjectURL(stream);
      }

      // 苹果手机的系统弹框会阻止js的线程的继续执行 手动0.1秒之后自动执行代码
      setTimeout(() => {
        video.play();
        this.initTracker(); // 人脸捕捉
      }, 100);
    },
    // 失败回调
    handleError(err) {
      this.scanTip = "访问用户媒体失败";
    },
    playVideo() {
      this.getUserMedia({
        //摄像头拍摄的区域
        video: {
          width: 500,
          height: 500,
          facingMode: "user",
        } /* 前置优先 */,
      });
    },
    onSubmit(values) {
      console.log("submit", values);
      if (values.fileList.length < 1) {
        this.$notify({ type: "warning", message: "请上传身份证正反面" });
      } else {
        this.$notify({ type: "success", message: "上传成功" });
      }
    },
    afterRead(file) {
      // 上传回调
      console.log(file);
    },
  },
};
</script>
<style lang="scss" scoped>
#seePerson {
  height: 100%;
  .face-capture {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    .img-cover {
      position: fixed;
      top: 63px;
      width: 100%;
      height: 100%;
      object-fit: cover;
      z-index: 3;
      background-repeat: no-repeat;
      background-size: 100% 100%;
    }
    .yuan {
      position: fixed;
      //   top: 63px;
      top: 100px;
      width: 100%;
      height: 49%;
      object-fit: cover;
      z-index: 3;
      //   background-repeat: no-repeat;
      //   background-size: 100% 100%;
      border: 1px solid #ccc;
      border-radius: 50%;
    }
    .contentp {
      position: fixed;
      top: 398px;
      font-size: 18px;
      font-weight: 500;
      color: #333333;
    }
    .rect {
      border: 2px solid #0aeb08;
      position: fixed;
      z-index: 4;
    }
    video,
    canvas {
      position: fixed;
      top: 101px;
      width: 100%;
      height: auto;
      object-fit: cover;
      z-index: 1;
      background-repeat: no-repeat;
      background-size: 100% 100%;
      border-radius: 50%;
    }
  }

  .tip {
    position: fixed;
    top: 48px;
    z-index: 5;
    font-size: 18px;
    font-family: PingFangSC-Medium, PingFang SC;
    font-weight: 500;
    color: #333333;
    line-height: 25px;
  }

  .img-face {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    .imgurl {
      position: fixed;
      top: 117.5px;
      width: 100%;
      height: auto;
      border-radius: 50%;
    }
  }
  .btn-face {
    width: 100%;
    display: flex;
    justify-content: center;
    .btn-face {
      bottom: 200px;
      position: fixed;
    }
  }
  .face-card {
    position: absolute;
    top: 60%;
    width: 100%;
  }
}
</style>
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值