调用本地摄像头进行拍照
摄像头取景框为圆形,照片为矩形
<template>
<div>
<div class="videoDiv">
<!-- 摄像头 -->
<video
id="videoCamera"
style="border-radius: 50%"
:width="videoWidth"
:height="videoHeight"
></video>
<!-- 幕布 -->
<canvas
id="canvasCamera"
width="300"
height="300"
></canvas>
</div>
<br />
<div v-if="imgSrc" class="imageDiv">
<!-- 图片 -->
<img :src="imgSrc" class="img_camera" />
</div>
<br />
<div class="buttonDiv">
<el-button type="primary" @click="openCamera">打开摄像头</el-button>
<el-button type="primary" @click="takePhoto">拍照</el-button>
<el-button type="primary" @click="closeCamera">关闭摄像头</el-button>
</div>
</div>
</template>
<script>
//这里可以导入其他文件(比如:组件,工具js,第三方插件js,json文件,图片文件等等)
//例如:import 《组件名称》 from '《组件路径》';
export default {
//import引入的组件需要注入到对象中才能使用
components: {},
data() {
//这里存放数据
return {
videoWidth: 300,
videoHeight: 300,
imgSrc: "",
thisCanvas: null,
thisVideo: null,
thisContext: null,
};
},
//方法集合
methods: {
//打开摄像头
openCamera() {
//_this只是一个变量名,this代表父函数,如果在子函数还用this,this的指向就变成子函数了,_this就是用来存储指向的
//函数中还有子函数的,用 _this 来代表父函数中的 this
var _this = this;
//定义幕布
this.thisCanvas = document.getElementById("canvasCamera");
//设置环境为2d
this.thisContext = this.thisCanvas.getContext("2d");
//定义相机
this.thisVideo = document.getElementById("videoCamera");
//判断浏览器是否支持mediaDevices
if (navigator.mediaDevices === undefined) {
//不支持,设置一个空对象
navigator.mediaDevices = {};
}
//判断浏览器是否缺少getUserMedia属性
if (navigator.mediaDevices.getUserMedia === undefined) {
//缺少getUserMedia属性,添加该属性
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")
);
}
//否则,使用Promis将调用方法包装到旧的getUserMedia中
return new Promise(function (resolve, reject) {
getUserMedia.call(navigator, constraints, resolve, reject);
});
};
}
//定义 constraints
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);
});
},
//关闭摄像头
closeCamera() {
this.thisVideo.srcObject.getTracks()[0].stop();
},
//拍照功能
takePhoto() {
var _this = this;
//点击canvas画图
_this.thisContext.drawImage(_this.thisVideo, 0, 0, 300, 300);
//获取图片base64连接
var image = this.thisCanvas.toDataURL("/image/png");
_this.imgSrc = image;
this.$emit("refreshDataList", this.imgSrc);
},
//base64转文件
dataURLtoFile(dataurl, fileName) {
var arr = dataurl.split(",");
var mime = arr[0].match(/:(.*?);/)[1];
var bstr = atob(arr[1]);
var u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new File([u8arr], fileName, { type: mime });
},
},
//生命周期 - 创建完成(可以访问当前this实例)
created() {},
};
</script>
<style scoped>
/* @import url(); 引入公共css类 */
.videoDiv {
text-align: center;
height: 500;
}
.imageDiv{
text-align: center;
height: 400;
}
.buttonDiv {
text-align: center;
}
</style>

浙公网安备 33010602011771号