vue中调用本地摄像头拍照生成base64的图像
复制可以直接使用
<template>
<div class="main">
<el-card>
<div slot="header">
<div>
<span>拍照</span>
<i @click="drawImage(true)" class="el-icon-refresh"></i>
</div>
</div>
<div>
<div class="camera_outer" ref="imgbg">
<div>
<video
style="display: none"
id="videoCamera"
:width="videoWidth"
:height="videoHeight"
muted
autoplay
></video>
<canvas
style="display: none"
id="canvasCamera"
:width="videoWidth"
:height="videoHeight"
></canvas>
</div>
<div v-if="imgSrc" class="img_bg_camera">
<img :src="imgSrc" alt class="tx_img" />
</div>
</div>
</div>
</el-card>
</div>
</template>
<script>
export default {
components: {},
data() {
return {
/** 照相机弹窗模块-start */
imgSrc: undefined,
thisVideo: null,
thisContext: null,
thisCancas: null,
videoWidth: 250,
videoHeight: 130,
takePhotos: true, // 控制警告弹窗
/** 照相机弹窗模块-end */
};
},
mounted() {
this.init();
},
beforeDestroy() {
this.stopNavigator();
},
methods: {
init() {
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.menavigatordiaDevices = {};
}
// 一些浏览器实现了部分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 () {
_this.thisVideo.play();
};
_this.takePhotos = true;
})
.catch(err => {
_this.takePhotos = false;
console.log(err);
});
});
},
//绘制图片
drawImage() {
if (!this.takePhotos) {
this.imgSrc = '';
this.$message.error($t('未检测到摄像设备,或未打开权限'));
return;
}
// 点击,canvas画图
this.thisContext.drawImage(
this.thisVideo,
0,
0,
this.videoWidth,
this.videoHeight
);
// 获取图片base64链接,展示到界面中的也是这个url地址
this.imgSrc = this.thisCancas.toDataURL('image/png');
},
//清除
stopNavigator() {
if (this.thisVideo && this.thisVideo !== null) {
this.thisVideo = null;
this.imgSrc = '';
}
},
},
computed: {},
};
</script>
<style lang="scss" scoped>
.camera_outer {
width: 100%;
height: 130px;
.img_bg_camera {
height: 130px;
img {
width: 100%;
height: 100%;
}
}
}
</style>