vue调用电脑摄像头,并利用canvas视频截图
<template> <div class="form-box"> <el-form :model="form" :rules="rules" ref="ruleForm" label-width="100px" class="demo-studentForm"> <el-form-item label="人脸信息" prop="faceBytes"> <el-image :src="form.faceBytes" class="img-box mini-img"> <div slot="error" class="image-slot" style="text-align: center;font-size: 20px;"> 请先拍照 --> </div> </el-image> <el-button @click="handleOpen" size="small" style="position: relative;top:-10px;left: 10px;">{{form.faceBytes ? '重新拍照' : '点击拍照'}}</el-button> </el-form-item> </el-form> <el-row> <el-col :span="12" style="text-align: right;"> <el-button @click="clearForm" type="warning" size="small">清 空</el-button> <el-button type="primary" @click="submitForm" size="small">确 定</el-button> </el-col> </el-row> <el-dialog title="摄像头拍照" :visible.sync="cameraOpen" :show-close="false" :close-on-press-escap="false" :close-on-click-modal="false"> <el-row> <el-col :span="12"> <p class="title">摄 像 头</p> <!-- 这里就是摄像头显示的画面 --> <video id="videoCamera" class="video-box"></video> </el-col> <el-col :span="12"> <p class="title">照 片</p> <!-- 这里是点击拍照显示的图片画面 --> <img v-show="form.faceBytes" :src="form.faceBytes" class="img-box" /> <canvas id="canvasCamera" class="canvas" :width='videoWidth' :height='videoHeight' style="display: none;"></canvas> </el-col> </el-row> <el-row> <el-col :span="12"> <el-button type="primary" icon="el-icon-camera" @click="drawImage">{{form.faceBytes ? '重新拍照' : '拍照'}}</el-button> </el-col> <el-col :span="12"> <el-button v-show="form.faceBytes" type="primary" icon="el-icon-check" @click="closeCameraMask">确定照片</el-button> </el-col> </el-row> </el-dialog> </div> </template> <script> import { mapState, mapMutations } from 'vuex' export default { data() { return { form: { faceBytes: "", }, rules: { faceBytes: [{ required: true, message: '请录入人脸信息', trigger: 'blur' }], }, /** 照相机弹窗模块-start */ cameraOpen: false, thisVideo: null, thisContext: null, thisCancas: null, videoWidth: 800, videoHeight: 600, /** 照相机弹窗模块-end */ } }, methods: {/** 调用摄像头拍照-start*/ // 打开照相机弹窗 handleOpen() { this.cameraOpen = true; this.getCompetence(); }, // 调用摄像头权限 getCompetence() { //必须在model中render后才可获取到dom节点,直接获取无法获取到model中的dom节点 this.$nextTick(() => { const _this = this; this.thisCancas = document.getElementById('canvasCamera'); //这里是需要截取的canvas的Id名称 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(如果存在) let 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) }) } } const 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) this.$notify({ title: '警告', message: '没有开启摄像头权限或浏览器版本不兼容.', type: 'warning' }); }); }); }, //绘制图片 drawImage() { // 点击,canvas画图 this.thisContext.drawImage(this.thisVideo, 0, 0, this.videoWidth, this.videoHeight); // 获取图片base64链接,展示到界面中的也是这个url地址 this.form.faceBytes = this.thisCancas.toDataURL('image/png'); }, //重置画布 resetCanvas() { this.form.faceBytes = ""; this.thisContext.clearRect(0, 0, c.width, c.height); }, // 关闭照相机弹窗 closeCameraMask() { this.cameraOpen = false; // 关闭照相机弹窗 // 关闭摄像头 if (this.thisVideo && this.thisVideo !== null) { this.thisVideo.srcObject.getTracks()[0].stop(); } }, /** 调用摄像头拍照-end*/ submitForm() { this.$refs.ruleForm.validate((valid) => { if (!valid) return false; this.$api.addSignin(this.form).then(res => { if (res) this.clearForm() }) }); }, // 清空数据 clearForm(formName) { this.$refs.ruleForm.resetFields(); } }, }; </script>