vue项目中实现拍照功能

vue文件中

 1 <!--开启摄像头的弹窗-->
 2 <div class="info2" @click="onTake">
 3   <el-image :src="url" style="width: 100%; height: 100%"></el-image>
 4 </div>
 5 
 6 <!--开启摄像头的拍照和-->
 7 <el-dialog title="拍照上传" :visible.sync="visible" @close="onCancel1" width="1065px">
 8   <div class="box">
 9     <video id="videoCamera" class="canvas" :width="videoWidth" :height="videoHeight" autoPlay></video>
10     <canvas id="canvasCamera" class="canvas" :width="videoWidth" :height="videoHeight"></canvas>
11   </div>
12   <div slot="footer">
13     <el-button @click="drawImage" icon="el-icon-camera" size="small">
14       拍照
15     </el-button>
16     <el-button v-if="os" @click="getCompetence" icon="el-icon-video-camera" size="small">
17       打开摄像头
18     </el-button>
19     <el-button v-else @click="stopNavigator" icon="el-icon-switch-button" size="small">
20       关闭摄像头
21     </el-button>
22     <el-button @click="resetCanvas" icon="el-icon-refresh" size="small">
23       重置
24     </el-button>
25     <el-button @click="onCancel" icon="el-icon-circle-close" size="small">
26       完成
27     </el-button>
28   </div>
29 </el-dialog>

js

  1 //对参数进行设置
  2 data() {
  3   return {
  4     url:"",// 上传的图片的地址
  5     visible: false, //弹窗
  6     videoWidth: 500,// 绘画布的宽高
  7     videoHeight: 400,
  8     os: false, //控制摄像头开关
  9     thisCancas: null,
 10     thisContext: null,
 11     thisVideo: null,
 12     imgSrc: undefined,
 13     imgFile: null,
 14   }
 15 }
 16 /*调用摄像头拍照开始*/
 17 onTake() {
 18   this.visible = true;
 19   this.getCompetence();
 20 },
 21 
 22 /*关闭弹窗,以及关闭摄像头功能*/
 23 onCancel1() {
 24   this.visible = false;
 25   this.stopNavigator(); // 关闭摄像头
 26 },
 27 
 28 // 调用摄像头权限
 29 getCompetence() {
 30   //必须在model中render后才可获取到dom节点,直接获取无法获取到model中的dom节点
 31   this.$nextTick(() => {
 32     const _this = this;
 33     this.os = false; //切换成关闭摄像头
 34     // 获取画布节点
 35     this.thisCancas = document.getElementById("canvasCamera");
 36     // 为画布指定绘画为2d类型
 37     this.thisContext = this.thisCancas.getContext("2d");
 38     //获取video节点
 39     this.thisVideo = document.getElementById("videoCamera");
 40     // 旧版本浏览器可能根本不支持mediaDevices,我们首先设置一个空对象
 41     if (navigator.mediaDevices === undefined) {
 42       navigator.menavigatordiaDevices = {};
 43     }
 44     // 一些浏览器实现了部分mediaDevices,我们不能只分配一个对象
 45     // 使用getUserMedia,因为它会覆盖现有的属性。
 46     // 这里,如果缺少getUserMedia属性,就添加它。
 47     if (navigator.mediaDevices.getUserMedia === undefined) {
 48       navigator.mediaDevices.getUserMedia = function(constraints) {
 49         // 首先获取现存的getUserMedia(如果存在)
 50         let getUserMedia =
 51           navigator.webkitGetUserMedia ||
 52           navigator.mozGetUserMedia ||
 53           navigator.getUserMedia;
 54         // 有些浏览器不支持,会返回错误信息
 55         // 保持接口一致
 56         if (!getUserMedia) {
 57           return Promise.reject(
 58             new Error("getUserMedia is not implemented in this browser")
 59           );
 60         }
 61         // 否则,使用Promise将调用包装到旧的navigator.getUserMedia
 62         return new Promise(function(resolve, reject) {
 63           getUserMedia.call(navigator, constraints, resolve, reject);
 64         });
 65       };
 66     }
 67     const constraints = {
 68       audio: false,
 69       video: {
 70         width: _this.videoWidth,
 71         height: _this.videoHeight,
 72         transform: "scaleX(-1)"
 73       }
 74     };
 75     navigator.mediaDevices
 76       .getUserMedia(constraints)
 77       .then(function(stream) {
 78         // 旧的浏览器可能没有srcObject
 79         if ("srcObject" in _this.thisVideo) {
 80           _this.thisVideo.srcObject = stream;
 81         } else {
 82           // 避免在新的浏览器中使用它,因为它正在被弃用。
 83           _this.thisVideo.src = window.URL.createObjectURL(stream);
 84         }
 85         _this.thisVideo.onloadedmetadata = function(e) {
 86           _this.thisVideo.play();
 87         };
 88       })
 89       .catch(err => {
 90         this.$notify({
 91           title: "警告",
 92           message: "没有开启摄像头权限或浏览器版本不兼容.",
 93           type: "warning"
 94         });
 95       });
 96   });
 97 },
 98 
 99 //调用摄像头 --- 进行绘制图片
100 drawImage() {
101   // 点击,canvas画图
102   this.thisContext.drawImage(
103     this.thisVideo,
104     0,
105     0,
106     this.videoWidth,
107     this.videoHeight
108   );
109   // 获取图片base64链接
110   this.imgSrc = this.thisCancas.toDataURL("image/png");
111 
112   /*const imgSrc=this.imgSrc;*/
113 },
114 //清空画布
115 clearCanvas(id) {
116   let c = document.getElementById(id);
117   let cxt = c.getContext("2d");
118   cxt.clearRect(0, 0, c.width, c.height);
119 },
120 
121 //重置画布
122 resetCanvas() {
123   // this.imgSrc = "";
124   this.clearCanvas("canvasCamera");
125 },
126 
127 //关闭摄像头
128 stopNavigator() {
129   if (this.thisVideo && this.thisVideo !== null) {
130     this.thisVideo.srcObject.getTracks()[0].stop();
131     this.os = true; //切换成打开摄像头
132   }
133 }
134 /*调用摄像头拍照结束*/
135 
136 /*完成拍照并对其照片进行上传*/
137 onCancel() {
138   this.visible = false;
139   /* this.resetCanvas();*/
140   // console.log(this.imgSrc);
141   this.imgFile = this.dataURLtoFile(this.imgSrc, new Date() + ".png");
142   console.log(this.imgFile);
143   this.stopNavigator();
144   // let par = {
145   //   photo: this.imgFile,
146   // };
147   let data = new FormData();
148   data.append("photo", this.imgFile); //1是图片,2是视频
149   // data.append("code", this.addForm.code);
150   console.log(data);
151   // checkbeforepersonalphoto上传图片的接口
152   checkbeforepersonalphoto(data).then(res => {
153     if (res.code == "1") {
154       this.$message({
155         message: "上传成功",
156         type: "success"
157       });
158       this.url = res.data;
159     }
160   });
161 },
162 
163 dataURLtoFile(dataurl, filename) {
164   var arr = dataurl.split(",");
165   var mime = arr[0].match(/:(.*?);/)[1];
166   var bstr = atob(arr[1]);
167   var n = bstr.length;
168   var u8arr = new Uint8Array(n);
169   while (n--) {
170     u8arr[n] = bstr.charCodeAt(n);
171   }
172   return new File([u8arr], filename, { type: mime });
173 },

css

.info2 {
  width: 10%;
  height: 100px;
}
.box {
  display:flex;
}

 

posted @ 2021-07-30 15:18  浪魔  阅读(1648)  评论(0编辑  收藏  举报