VUE 小技巧 (1) -- 调用电脑摄像头拍照
1. 添加展示节点
<template>
<div>
<!--判断 浏览器类型 非IE浏览器-->
<div class="video-box" v-if="!isIE">
<video id="video" width="320" height="240"></video>
<!--不显示-->
<canvas id="canvas1" width="320" height="240"></canvas>
</div>
<!--判断 浏览器类型 IE浏览器-->
<div class="ie-box" v-if="isIE">
<!--jq 调用展示-->
<div id="webcam"></div>
<!--不显示-->
<canvas id="canvas2" width="320" height="240"></canvas>
</div>
<!--图片展示-->
<div class="img-box">
<!--默认图-->
<i v-if="!faceUrl" class="el-icon-s-custom"></i>
<!--展示图-->
<img v-if="faceUrl" :src="faceUrl" alt="" />
</div>
<el-button type="primary" @click="onPhoto()">拍 照</el-button>
<el-button type="primary" @click="onPhotoSure()">确定</el-button>
</div>
</template>
2. 配置 JS
需要区分浏览器 IE浏览器需要通过JQ调用
export default {
data() {
return {
isIE: false, // 判断当前打开浏览器是否为IE浏览器
photoUrl: null, // 人脸识别成功后最终的照片地址
faceUrl: null, // 这个是在调取摄像头后拍照过程中产生的图片预览地址
mediaStreamTrack: null, // 谷歌内核的摄像头关闭亮灯就靠它
$jq: null, // 把jquery赋值给它,由于受eslint的影响,即使全局引入了jQuey,也不能直接使用$符号
};
},
created() {
this.isIE = this.adjustIE(); // 判断是否为IE浏览器
this.$jq = $; // 把jquery赋值给它,由于受eslint的影响,即使全局引入了jQuey,也不能直接使用$符号
},
methods: {
// 判断是否为IE浏览器
adjustIE() {
const explorer = window.navigator.userAgent.toLowerCase();
// ie
if (explorer.indexOf('msie') >= 0) {
return true;
} else if (explorer.indexOf('rv') >= 0 && explorer.indexOf('firefox') == -1) {
return true;
} else {
return false;
}
},
// 点击人脸识别的按钮
onFace() {
this.show.cameraShow = true;
// 调起浏览器的摄像头
this.callCamera();
},
// 关闭人脸识别拍照的窗口
closeFace() {
this.faceUrl = null;
if (!this.isIE) {
this.mediaStreamTrack && this.mediaStreamTrack.stop();
} else {
this.webcamShow = false;
}
},
// 关闭之前IE浏览器的话就再初始化一遍,目的是为了关闭摄像头的亮着的小灯
handleClose(done) {
if (this.isIE) {
this.$jq('#XwebcamXobjectX').remove();
this.iEcallCamera();
}
done();
},
// 访问用户媒体设备的兼容方法
getUserMedia(constraints, success, error) {
if (window.navigator.mediaDevices.getUserMedia) {
// 最新的标准API
window.navigator.mediaDevices.getUserMedia(constraints).then(success).catch(error);
} else if (window.navigator.webkitGetUserMedia) {
// webkit核心浏览器
window.navigator.webkitGetUserMedia(constraints, success, error);
} else if (window.navigator.mozGetUserMedia) {
// firfox浏览器
window.navigator.mozGetUserMedia(constraints, success, error);
} else if (window.navigator.getUserMedia) {
// 旧版API
window.navigator.getUserMedia(constraints, success, error);
}
},
// 谷歌内核调取摄像头成功的回调
photographSuccess(stream) {
// 兼容webkit核心浏览器
const video = document.getElementById('video');
// 将视频流设置为video元素的源
video.srcObject = stream;
this.mediaStreamTrack = typeof stream.stop === 'function' ? stream : stream.getTracks()[0];
video.play();
},
// 谷歌内核调取摄像头失败的回调
photographError(error) {
console.log(`访问用户媒体设备失败${error.name}, ${error.message}`);
},
// 调取摄像头
callCamera() {
this.$nextTick(() => {
if (this.isIE) {
this.webcamShow = true;
this.iEcallCamera();
} else {
if (window.navigator.mediaDevices.getUserMedia || window.navigator.getUserMedia || window.navigator.webkitGetUserMedia || window.navigator.mozGetUserMedia) {
// 调用用户媒体设备, 访问摄像头
this.getUserMedia({
video: {
width: 320,
height: 240
}
}, this.photographSuccess, this.photographError);
} else {
alert('不支持访问用户媒体');
}
}
});
},
// ie浏览器通过jquery插件来调取摄像头
iEcallCamera() {
this.$nextTick(() => {
const w = 320;
const h = 240; // 摄像头配置,创建canvas
let pos = 0;
let ctx = null;
let image = [];
const canvas = document.getElementById('canvas');
ctx = canvas.getContext('2d');
const _this = this;
image = ctx.getImageData(0, 0, w, h);
this.$jq('#webcam').webcam({
width: w,
height: h,
mode: 'callback', // stream,save,回调模式,流模式和保存模式
swffile: '/js/jscam_canvas_only.swf',
onTick: function (remain) {
console.log('🚀~~🚀', remain);
},
onSave: function (data) { // 保存图像
const col = data.split(';');
const img = image;
for (let i = 0; i < w; i++) {
const tmp = parseInt(col[i]);
img.data[pos + 0] = (tmp >> 16) & 0xff;
img.data[pos + 1] = (tmp >> 8) & 0xff;
img.data[pos + 2] = tmp & 0xff;
img.data[pos + 3] = 0xff;
pos += 4;
}
if (pos >= 4 * w * h) {
ctx.putImageData(img, 0, 0); // 转换图像数据,渲染canvas
pos = 0;
_this.faceUrl = canvas.toDataURL('image/png'); // 上传给后台的图片数据
}
},
onCapture: function () { // 捕获图像
window.webcam.save();
},
debug: function (type, string) { // 控制台信息
console.log(type + ': ' + string);
},
onLoad: function () { // flash 加载完毕执行
const cams = window.webcam.getCameraList();
for (const i in cams) {
_this.$jq('body').append('<p>' + cams[i] + '</p>');
}
}
});
});
},
// 点击拍照按钮
onPhoto() {
if (this.isIE) {
window.webcam.capture();
} else {
const canvas = document.getElementById('canvas');
const context = canvas.getContext('2d');
const video = document.getElementById('video');
context.drawImage(video, 0, 0, 320, 240);
this.faceUrl = canvas.toDataURL('image/png');
}
},
// 拍照完点击确定按钮
onPhotoSure() {
// 经过人脸识别的ajax请求接口成功后
// 获取图片地址
this.photoUrl = this.faceUrl;
}
}
}
</script>