vue 电脑摄像头拍照

我的需求是, 打开摄像头, 拍照后, 把文件上传到服务器; 过程不是很顺利, 所以记录一下. 放置打开摄像头的按钮的页面就不写了, 主要写摄像头页面;

注意:  服务必须是安全链接  https 的才可以, 否则无法使用摄像头 

<template>
    <div>
        <el-row :gutter="16">
            <el-col :span="12">
                <!--图片展示-->
                <video ref="video" :width="canvasW" :height="canvasH" autoplay/>
            </el-col>
            <el-col :span="12" >
                <!--canvas截取流-->
                <div class="avatar-uploader">
                    <canvas ref="canvas" :width="canvasW" :height="canvasH"/>
                </div>
            </el-col>
        </el-row>
        <el-row class="camera-button" :gutter="16">
            <!--确认-->
            <el-col :span="12">
                <el-button type="primary" @click="photograph">拍照</el-button>
            </el-col>
            <el-col :span="12">
                <el-button type="primary" @click="refreshCanvas" plain>重拍</el-button>
            </el-col>
        </el-row>
    </div>

</template>

<script>
  import store from "../../../store";

  export default {
    props:['fileName','customerId',],
    data() {
      return {
        action: `filedoc/file/doc/uploadUnusedSingle`,
        addFaceAction: 'basicdata/thirdParty/face/upload',
        checkFaceAction: 'basicdata/thirdParty/face/check',
        headImgSrc: '/img/code/wechat-code.jpg',
        canvasH: 340,
        canvasW: 401,
        imgBase64: '',
        faceFiles: [],
      }
    },
    mounted() {
      let _this = this;
      this.callCamera();
      // 查询门禁图片
      this.postRequest("basicdata/thirdParty/face/get", {customerId: _this.customerId}, function(data) {
        _this.faceFiles = data;
      });
    },
    beforeDestroy() {
      this.closeCamera();
    },
    methods: {
      // 调用摄像头
      callCamera() {
        // H5调用电脑摄像头API, 指定最低像素, 期望像素和最高像素
        navigator.mediaDevices.getUserMedia({
          video: { width: { min: 1280, ideal: 1920, max: 1920 },
            height: { min: 720, ideal: 1080, max: 1080 }
          }
        }).then(success => {
          // 摄像头开启成功
          this.$refs['video'].srcObject = success;
          // 实时拍照效果
          this.$refs['video'].play();
        }).catch(error => {
          console.error('摄像头开启失败,请检查摄像头是否可用!')
        })
      },
      // 拍照
      photograph() {
        let ctx = this.$refs['canvas'].getContext('2d');
        // 把当前视频帧内容渲染到canvas上
        ctx.drawImage(this.$refs['video'], 0, 0, this.canvasW, this.canvasH);
        // 转base64格式、图片格式转换、图片质量压缩
        this.imgBase64 = this.$refs['canvas'].toDataURL('image/jpeg');

        // 由字节转换为KB 判断大小
        // let imgCode = this.imgBase64.replace('data:image/jpeg;base64,', '');

        // // 图片尺寸  用于判断
        // let strLength = imgCode.length;
        // let fileLength = parseInt(strLength - (strLength / 8) * 2);
        // let size = (fileLength / 1024).toFixed(2);

        // 保存到本地
        // let ADOM = document.createElement('a');
        // ADOM.href = this.headImgSrc;
        // ADOM.download = new Date().getTime() + '.jpeg';
        // ADOM.click();
      },
      // 清除照片
      refreshCanvas() {
        let ctx = this.$refs['canvas'].getContext('2d');
        ctx.clearRect(0, 0, this.canvasW, this.canvasH);
        this.imgBase64 = '';
      },
      // 关闭摄像头
      closeCamera() {
        if (!this.$refs['video'].srcObject) return;
        let stream = this.$refs['video'].srcObject;
        let tracks = stream.getTracks();
        tracks.forEach(track => {
          track.stop()
        });
        this.$refs['video'].srcObject = null;
      },
      // 上传前的校验
      beforeAvatarUpload(file) {
        // 最大664 KB
        const isLt2M = file.size / 1024 < 646;
        if (!isLt2M) {
          this.$message({
            message: '上传头像图片大小不能超过 646KB!',
            type: 'warning'
          });
        }
        return  isLt2M;
      },
      // 上传人脸信息, 绑定文件和人员关系
      uploadAvatar() {
        let _this = this;
        if(!this.imgBase64){
          this.$message({
            message: '请拍摄照片后再上传',
            type: 'warning'
          });
          return;
        }
        let file = this.dataURLtoFile(this.imgBase64, this.fileName);
        let faceBase64 = this.imgBase64.replace('data:image/jpeg;base64,', '').replace('data:image/jpg;base64,', '');
        if(this.beforeAvatarUpload(file)){
          let formData = new FormData();
          const userId = store.getters["login/userId"];
          formData.append("uploadUserId", userId);
          formData.append('file', file);
          this.uploadFileRequest(this.action, formData, data =>{
            if(data && data.id){
              let param = {customerId: _this.customerId, fileId: data.id, faceBase64};
              this.postRequest(this.addFaceAction, param, data=>{
                 if(data==="success"){
                   this.$emit('getFace', _this.customerId);
                   this.$notify({
                     title: '成功',
                     message: '上传成功',
                     type: 'success'
                   });
                   this.$emit('closeCamera');
                 }else{
                   this.$message({
                     message: data,
                     type: 'warning'
                   });
                 }
              });
            }
          });
        }
      },

      //将base64转换为blob
      dataURLtoBlob(dataurl) {
        var arr = dataurl.split(','),
          mime = arr[0].match(/:(.*?);/)[1],
          bstr = atob(arr[1]),
          n = bstr.length,
          u8arr = new Uint8Array(n);
        while (n--) {
          u8arr[n] = bstr.charCodeAt(n);
        }
        return new Blob([u8arr], { type: mime });
      },
      // 将blob转换为file
      blobToFile(theBlob, fileName){
        theBlob.lastModifiedDate = new Date();
        theBlob.name = fileName;
        return new File([theBlob], fileName);
      },
      // base64 转 file
      dataURLtoFile(dataurl, filename='faceImg.jpg') {
        let blobT = this.dataURLtoBlob(dataurl);
        return this.blobToFile(blobT,filename);
      }

    }
  }
</script>

<style scoped>
    .camera-button {
        text-align: center;
        width: 100%;
        margin: 0.2rem 0 0 0;
    }

    .avatar-uploader {
        border: 1px dashed #d9d9d9;
        border-radius: 6px;
        cursor: pointer;
        position: relative;
        overflow: hidden;
        width: 401px;
        height: 300px;
        margin: 20px auto;
    }

</style>

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值