目录
效果展示
核心代码
相关问题
Error: getUserMedia is not implemented in this browser
DOMException: Permission denied
代码解析
HTML+JavaScript实现人脸识别页面,点击“人脸识别”按钮开始识别,扫描过程中有扫描条上下扫描,并且设置loading,扫描中不能再次人脸识别,前端捕获base64格式照片转file形式传递给后端做处理,若识别成功则跳转到主页面,识别失败则自动关闭人脸识别返回到本页面。
效果展示
人脸识别
核心代码
人脸识别:
<template> <div> <video id="videoCamera" :width="videoWidth" :height="videoHeight" class="camera_facing" autoplay > </video> <div class="saomiao" v-if="isVideo"></div> <canvas style="display:none;" id="canvasCamera" :width="videoWidth" :height="videoHeight" ></canvas> <div class="main-item-btn" @click="getCompetence()"> <el-button class="main-foot-button" :disabled="isVideo" >人脸识别</el-button> </div> </div> </template> <script> import { faceRecognize } from "@/request/api/faceRecognize.js"; export default { inject:['reload'], data() { return { videoWidth: 435, videoHeight: 435, thisCancas: null, thisContext: null, thisVideo: null, isVideo : false, } }, methods: { getCompetence () { this.isVideo = true; var _this = this this.thisCancas = document.getElementById('canvasCamera') this.thisContext = this.thisCancas.getContext('2d') this.thisVideo = document.getElementById('videoCamera') if (navigator.mediaDevices === undefined) { navigator.mediaDevices = {} } if (navigator.mediaDevices.getUserMedia === undefined) { navigator.mediaDevices.getUserMedia = function (constraints) { var getUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.getUserMedia if (!getUserMedia) { return Promise.reject(new Error('getUserMedia is not implemented in this browser')) } return new Promise(function (resolve, reject) { getUserMedia.call(navigator, constraints, resolve, reject) }) } } var constraints = { audio: false, video: { width: this.videoWidth, height: this.videoHeight, transform: 'scaleX(-1)' } } navigator.mediaDevices.getUserMedia(constraints).then(function (stream) { 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.isVideo = false; }) setTimeout(() => { _this.setImage(); }, 5000) }, // 绘制图片(拍照功能) setImage () { var _this = this // 按比例压缩4倍 var rate = (_this.videoWidth < _this.videoHeight ? _this.videoWidth / _this.videoHeight : _this.videoHeight / _this.videoWidth) / 5; this.thisCancas.width = _this.videoWidth * rate; this.thisCancas.height = _this.videoHeight * rate; // 点击,canvas画图 _this.thisContext.drawImage(_this.thisVideo, 0, 0, _this.videoWidth, _this.videoHeight, 0, 0, _this.videoWidth * rate, _this.videoHeight * rate) // 获取图片base64链接 var image = this.thisCancas.toDataURL('image/png'); var imgSrc = this.dataURLtoFile(image, "person.png"); let formData = new FormData(); formData.append("file", imgSrc); faceRecognize(formData).then(res => { if(res.code === 200) { this.$store.commit("userInfo/UPDATE_ALL_USER_INFO", res.data) this.$router.push("/index"); }else if(res.code === 500){ this.$message.error(res.msg); this.reload(); }else{ this.$message.error("认证失败"); this.reload(); } this.isVideo = false; }) .catch(()=>{ this.$message.error("认证失败"); this.reload(); this.isVideo = false; }) }, // base64转文件 dataURLtoFile (dataurl, filename) { var arr = dataurl.split(',') var mime = arr[0].match(/:(.*?);/)[1] var bstr = atob(arr[1]) var n = bstr.length var u8arr = new Uint8Array(n) while (n--) { u8arr[n] = bstr.charCodeAt(n) } return new File([u8arr], filename, { type: mime }) }, fullScreen() { var el = document.documentElement; var rfs = el.requestFullScreen || el.webkitRequestFullScreen || el.mozRequestFullScreen || el.msRequestFullScreen; if (typeof rfs != "undefined" && rfs) { rfs.call(el); } else if (typeof window.ActiveXObject != "undefined") { // for Internet Explorer var wscript = new ActiveXObject("WScript.Shell"); if (wscript != null) { wscript.SendKeys("{F11}"); } } } } } </script> <style lang="less" scoped> .saomiao { width: 75%; margin-top: 20%; height: 2px; background: linear-gradient(244deg, rgba(255, 255, 255, 0) 0%, #56dafe 50%, rgba(255, 255, 255, 0) 100%); position: absolute; left: 50%; transform: translateX(-50%); top: 0px; animation: move 3s ease-in-out infinite; -webkit-animation: move 3s ease-in-out infinite; } @keyframes move { from { top: 0px } /*网格移动到显示区域的外面*/ to { top: 400px } } </style>
复制
APP:
<template> <div id="app"> <router-view v-if="isRouterAlive"/> </div> </template> <script> export default { provide() { return { reload: this.reload }; }, data() { return { isRouterAlive: true }, methods: { reload() { this.isRouterAlive = false; this.$nextTick(function() { this.isRouterAlive = true; }); }, } } </script>
复制
相关问题
Error: getUserMedia is not implemented in this browser
后端接口可以调用,但是人脸识别摄像头未打开,报错:
若是edge浏览器则打开edge://flags/#unsafely-treat-insecure-origin-as-secure,chrome谷歌浏览器打开chrome://flags/#unsafely-treat-insecure-origin-as-secure,在Insecure origins treated as secure中输入自己的项目对应的ip和端口,点击Enabled并且重启。
DOMException: Permission denied
调用报的该异常,因为摄像头被禁止使用了,解决方法开启摄像头权限。
点击地址栏右侧摄像头图表,点击允许
代码解析
利用dom中HTML特征id属性查找其对应的<video><canvas>标签,在getCompetence()方法中若浏览器中缺少相关属性则添加mediaDevices和getUserMedia属性,并且设置人脸识别相机大小形状,在识别过程中利用isVideo属性确定是否显示扫描条,利用CSS3设置上下扫描动画,并且在扫描过程中利用isVideo不能点击按钮,以免重复不停调用后端接口,5秒后利用canvas画图获取base64图片,再次转换成file形式传到后端,若成功则自动跳转到index页面,若失败利用 provide
和 inject
实现页面刷新并且没有空白页面闪烁,重新返回到此页面。