调用本地摄像头进行拍照

摄像头取景框为圆形,照片为矩形

<template>
  <div>
    <div class="videoDiv">
      <!-- 摄像头 -->
      <video
        id="videoCamera"
        style="border-radius: 50%"
        :width="videoWidth"
        :height="videoHeight"
      ></video>
      <!-- 幕布 -->
      <canvas
        id="canvasCamera"
        width="300"
        height="300"
      ></canvas>
    </div>
    <br />
    <div v-if="imgSrc" class="imageDiv">
      <!-- 图片 -->
      <img :src="imgSrc" class="img_camera" />
    </div>
    <br />
    <div class="buttonDiv">
      <el-button type="primary" @click="openCamera">打开摄像头</el-button>
      <el-button type="primary" @click="takePhoto">拍照</el-button>
      <el-button type="primary" @click="closeCamera">关闭摄像头</el-button>
    </div>
  </div>
</template>

<script>
//这里可以导入其他文件(比如:组件,工具js,第三方插件js,json文件,图片文件等等)
//例如:import 《组件名称》 from '《组件路径》';

export default {
  //import引入的组件需要注入到对象中才能使用
  components: {},
  data() {
    //这里存放数据
    return {
      videoWidth: 300,
      videoHeight: 300,
      imgSrc: "",
      thisCanvas: null,
      thisVideo: null,
      thisContext: null,
    };
  },
  //方法集合
  methods: {
    //打开摄像头
    openCamera() {
      //_this只是一个变量名,this代表父函数,如果在子函数还用this,this的指向就变成子函数了,_this就是用来存储指向的
      //函数中还有子函数的,用 _this 来代表父函数中的 this
      var _this = this;
      //定义幕布
      this.thisCanvas = document.getElementById("canvasCamera");
      //设置环境为2d
      this.thisContext = this.thisCanvas.getContext("2d");
      //定义相机
      this.thisVideo = document.getElementById("videoCamera");
      //判断浏览器是否支持mediaDevices
      if (navigator.mediaDevices === undefined) {
        //不支持,设置一个空对象
        navigator.mediaDevices = {};
      }

      //判断浏览器是否缺少getUserMedia属性
      if (navigator.mediaDevices.getUserMedia === undefined) {
        //缺少getUserMedia属性,添加该属性
        navigator.mediaDevices.getUserMedia = function (constraints) {
          //如果现存 getUserMedia,将其获取
          var getUserMedia =
            navigator.webkitGetUserMedia ||
            navigator.mozGetUserMedia ||
            navigator.getUserMedia;
          //如果浏览器不支持,返回错误信息
          if (!getUserMedia) {
            return Promise.reject(
              new Error("getUserMedia is not implemented in this browser")
            );
          }
          //否则,使用Promis将调用方法包装到旧的getUserMedia中
          return new Promise(function (resolve, reject) {
            getUserMedia.call(navigator, constraints, resolve, reject);
          });
        };
      }
      //定义 constraints
      var constraints = {
        audio: false,
        video: {
          width: this.videoWidth,
          height: this.videoHeight,
          transform: "scaleX(-1)",
        },
      };

      navigator.mediaDevices
        .getUserMedia(constraints)
        .then(function (stream) {
          //判断浏览器中是否有 srcObject
          if ("srcObject" in _this.thisVideo) {
            //浏览器中存在
            _this.thisVideo.srcObject = stream;
          } else {
            //浏览器中不存在,因其正在被弃用,避免在新浏览器中使用它
            _this.thisVideo.src = window.URL.createObjectURL(stream);
          }
          _this.thisVideo.onloadedmetadata = function (e) {
            _this.thisVideo.play();
          };
        })
        .catch((err) => {
          console.log(err);
        });
    },
    //关闭摄像头
    closeCamera() {
      this.thisVideo.srcObject.getTracks()[0].stop();
    },
    //拍照功能
    takePhoto() {
      var _this = this;
      //点击canvas画图
      _this.thisContext.drawImage(_this.thisVideo, 0, 0, 300, 300);
      //获取图片base64连接
      var image = this.thisCanvas.toDataURL("/image/png");
      _this.imgSrc = image;
      this.$emit("refreshDataList", this.imgSrc);
    },

    //base64转文件
    dataURLtoFile(dataurl, fileName) {
      var arr = dataurl.split(",");
      var mime = arr[0].match(/:(.*?);/)[1];
      var bstr = atob(arr[1]);
      var u8arr = new Uint8Array(n);
      while (n--) {
        u8arr[n] = bstr.charCodeAt(n);
      }
      return new File([u8arr], fileName, { type: mime });
    },
  },
  //生命周期 - 创建完成(可以访问当前this实例)
  created() {},
};
</script>
<style scoped>
/* @import url(); 引入公共css类 */
.videoDiv {
  text-align: center;
  height: 500;
}
.imageDiv{
    text-align: center;
    height: 400;
}
.buttonDiv {
  text-align: center;
}
</style>

原文连接:https://www.cnblogs.com/Apsey/p/11865581.html

posted @ 2021-01-06 15:03  事有回响  阅读(273)  评论(0编辑  收藏  举报