vue+elementUI实现调用PC摄像头拍照上传图片(谷歌火狐测试可用,其他自测)

一定部署到https域名上,否则无法调用摄像头权限!!!

效果图

vue+elementUI实现调用PC摄像头拍照上传图片(谷歌火狐测试可用,其他自测)_第1张图片

定义Data

 data () {
      return {
        dialogTableVisible:false,
        videoWidth: 500,
        videoHeight: 400,
        imgSrc: '',
        thisCancas: null,
        thisContext: null,
        thisVideo: null,
        ImgFile:'',//返回的图片文件
      }
    },
调用摄像头权限
getCompetence () {
        this.$nextTick(function () {
          var _this = this;
          this.thisCancas = document.getElementById('canvasCamera');
          this.thisContext = this.thisCancas.getContext('2d');
          this.thisVideo = document.getElementById('videoCamera');
          // 旧版本浏览器可能根本不支持mediaDevices,我们首先设置一个空对象
          if (navigator.mediaDevices === undefined) {
            navigator.mediaDevices = {}
          }
          // 一些浏览器实现了部分mediaDevices,我们不能只分配一个对象
          // 使用getUserMedia,因为它会覆盖现有的属性。
          // 这里,如果缺少getUserMedia属性,就添加它。
          if (navigator.mediaDevices.getUserMedia === undefined) {
            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'))
              }
              // 否则,使用Promise将调用包装到旧的navigator.getUserMedia
              return new Promise(function (resolve, reject) {
                getUserMedia.call(navigator, constraints, resolve, reject)
              })
            }
          }

          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)
          })
        });
      },

绘制图片,生成一个base64文件

setImage(){
        var _this = this;
        // 点击,canvas画图
        _this.thisContext.drawImage(_this.thisVideo, 0, 0, _this.videoWidth, _this.videoHeight);
        // 获取图片base64链接
        var image = this.thisCancas.toDataURL('image/png');
        _this.imgSrc = image;
      },

base64文件转文件流

dataURLtoFile (dataurl, filename) {
        var arr = dataurl.split(',');
        var mime = arr[0].match(/:(.*?);/)[1];
        var bstr = atob(arr[1]);
        var n = bstr.length;
        var u8arr = new Uint8Array(n);
        while (n--) {
          u8arr[n] = bstr.charCodeAt(n)
        }
        return new File([u8arr], filename, { type: mime })
      },

上传文件流至后台(form提交)

handleUpdata(){//已form提交
        if (this.imgSrc!==''){
          let file = this.imgSrc; // 把整个base64给file
          let type = "image/jpeg"; // 定义图片类型(canvas转的图片一般都是png,也可以指定其他类型)
          let time=(new Date()).valueOf();//生成时间戳
          let name = time + ".jpg"; // 定义文件名字(例如:abc.png , cover.png)
          let conversions = this.dataURLtoFile(file, name); // 调用base64转图片方法
          let parms=new FormData();
          parms.append('file',conversions);
          let url='*********';//你的接口
          this.axios.post(url,parms,{headers: {'Content-Type': 'multipart/form-data'}}).then(res=>{
            console.log(res);
            this.ImgFile=res.data;
          }).catch(err=>{
            this.$notify.error({
              title: '上传失败',
              message: err.msg
            });
          })
        }
      },

关闭摄像头

stopNavigator () {
        this.thisVideo.srcObject.getTracks()[0].stop()
      },
 

离开页面时关闭摄像头

 beforeDestroy () {
      this.stopNavigator()
    }

附上源码:






 

你可能感兴趣的:(vue+elementUI实现调用PC摄像头拍照上传图片(谷歌火狐测试可用,其他自测))