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