一、思路
vue打开摄像头获取视频流数据->截取视频流通过canvas绘制图片->图片传到服务器识别(后端使用的是阿里的人脸识别api)
二、直接上代码<template>
<div class="face-area"> <div class="area-left"> <p>请将脸部正对摄像头并填充满取景框</p> <frame-1> <video id="video" autoplay></video> </frame-1> <button v-if="reFace" class="upload-btn" @click="openVideo">重新识别</button> </div> <div class="area-right"> <p>{{text}}</p> <canvas id="canvas" width="300" height="424"></canvas> </div> </div> </template> <script> import frame1 from '../components/frame1.vue'; export default { components: { frame1 }, props: { account:{ type:String }, type:{ type:Number } }, data() { return { context: {}, text:"人脸识别中...", mediaStreamTrack:{}, count:0, reFace:false, } }, methods: {
//关闭摄像头 closeMedia() { var _this=this; this.mediaStreamTrack.getVideoTracks().forEach(function (track) { track.stop(); _this.context.clearRect(0, 0, _this.context.width, _this.context.height); //清除画布 }); },
//打开摄像头 openVideo() { this.text="人脸识别中..." var canvas = document.getElementById("canvas"); this.context = canvas.getContext("2d"); this.video = document.getElementById("video"); if (navigator.mediaDevices === undefined) { navigator.mediaDevices = {} } //缺少getUserMedia属性 if (navigator.mediaDevices.getUserMedia === undefined) { navigator.mediaDevices.getUserMedia = function (constraints) { // 首先获取现存的getUserMedia(如果存在) var getUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia; // 浏览器不支持,返回错误信息 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); }); } } var constraints = { audio: false, video: { width: 600, height: 848, } } var _this=this; navigator.mediaDevices.getUserMedia(constraints) .then(function (stream) { var video = document.querySelector('video'); _this.mediaStreamTrack = stream; // 旧的浏览器可能没有srcObject if ("srcObject" in video) { video.srcObject = stream; } else { //避免在新的浏览器中使用它,因为它正在被弃用。 video.src = window.URL.createObjectURL(stream); } video.onloadedmetadata = function (e) { video.play(); //开始识别 if (_this.type == 1) { setTimeout(_this.getImg(), 500); } }; }) .catch(function (err) { console.log(err.name + ": " + err.message); _this.$confirm('是否前往查看设置教程?', '打开摄像头失败请检查浏览器设置或域名是否安全', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).then(() => { window.open("https://www.cnblogs.com/tuofei13/p/16636145.html", "_blank"); }) }); }, //截取人脸图片 getImg() { var date = new Date().getTime(); // 点击,canvas画图 this.context.drawImage(this.video, 0, 0, 300, 424); // 获取图片base64链接 var image = canvas.toDataURL('image/png'); // 定义一个img var img = new Image(); //设置属性和src img.id = "imgBox"; img.src = image; // console.log(image); if(this.type==0){ this.addFace(image.split(",")[1]); } else{ this.recognitionFace(image.split(",")[1]); } }, //上传到服务器比对结果 recognitionFace(image){ let params={ account:this.account, imageDataB:image, }; this.$http.post(this.$rconfig.basic("登录-人脸识别"), params) .then(res => { // console.log(res); if (res.code == 200) { this.text = "人脸匹配成功,登录中..." this.$message({ message: '人脸匹配成功', type: 'success' }); this.closeMedia() this.login(res); } else{ //递归识别 this.count++; if(this.count<=10){ this.getImg(); } else{ this.$message({ message: '识别失败次数过多,请稍后重试', type: 'warning', center: true }); this.count=0; this.text="识别失败次数过多,请稍后重试" this.reFace=true; this.closeMedia(); } } }) ; },// base64转文件 dataURLtoFile(dataurl, filename) { var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1], bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n); while (n--) { u8arr[n] = bstr.charCodeAt(n); } return new File([u8arr], filename, { type: mime }); }, //处理返回信息(菜单、缓存等)并登录 login(res) { //登录逻辑 }, }, mounted() { //当type为1时循环请求识别接口 setTimeout(this.openVideo, 600); }, destroyed(){ this.closeMedia(); } } </script> <style scoped> .face-area{ width: 100%; height: 100%; text-align: center; float: left; } .area-left{ width: 360px; height: 630px; float: left; text-align: center; } .area-right{ width: 640px; height: 632px; float: left; } .area-left p{ margin-top: 60px; font-size: 16px; color: #33dafd; height: 30px; line-height: 30px; } .area-right p { margin-top: 60px; font-size: 24px; height: 30px; line-height: 30px; text-align: center; background-image: -webkit-linear-gradient(left, #053744, #33dafd 25%, #147B96 50%, #33dafd 75%, #053744); -webkit-text-fill-color: transparent; -webkit-background-clip: text; background-clip: text; -webkit-background-size: 200% 100%; background-size: 200% 100%; animation: slideShine 2s infinite linear; } @keyframes slideShine { 0%{ background-position: 0 0;} 100% { background-position: -100% 0;} } #video{ width: 296px; height: 420px; margin: 2px; transform: rotateY(180deg);/* 摄像头呈镜像用样式左右翻转让人像动起来正常方便识别 */ } #canvas{ margin-top: 20px; border-radius: 10px; /* opacity:0 */ } .upload-btn{ border: none; height: 40px; width: 180px; line-height: 40px; background-color: #33dafd; color: #FFF; margin-top: 30px; } </style>
标签:vue,text,image,height,PC,人脸识别,video,getUserMedia,navigator From: https://www.cnblogs.com/tuofei13/p/16638058.html