qa-prevention-wlaq-vue/static/face/face_camera.html

253 lines
8.1 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>人脸识别</title>
<script src="./js/vue.js"></script>
<script type="text/javascript" src="./js/jquery-3.3.1.min.js"></script>
<script src="../config.js"></script>
<script src="build/tracking-min.js"></script>
<script src="build/data/face-min.js"></script>
<style>
#video {
transform: rotateY(180deg);
}
.face-capture {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.face-capture video, .face-capture canvas {
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
width: 100%;
height: 100%;
object-fit: cover;
z-index: 2;
background-repeat: no-repeat;
background-size: 100% 100%;
}
.face-capture canvas {
z-index: 2;
}
.face-capture .img-cover {
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
width: 100%;
height: 100%;
object-fit: cover;
z-index: 2;
background-repeat: no-repeat;
background-size: 100% 100%;
}
.face-capture .rect {
border: 2px solid #0aeb08;
position: fixed;
z-index: 3;
}
.face-capture .control-container {
margin-top: 10rem;
position: relative;
width: 100%;
height: 100%;
object-fit: cover;
z-index: 4;
background-repeat: no-repeat;
background-size: 100% 100%;
}
.face-capture .title {
text-align: center;
color: white;
margin: 1.6rem auto;
font-size: 28px;
}
.face-capture .close {
width: 0.8rem;
height: 0.8rem;
}
</style>
</head>
<body>
<div id="app">
<div v-show="showContainer" class="face-capture" id="face-capture">
<video ref="refVideo" id="video" autoplay></video>
<!-- <img src="./../images/video-cover.png" alt="cover" class="img-cover"/> -->
<div class="control-container face-capture">
<h2 class="title">{{scanTip}}</h2>
<h2 class="title">{{msg}}</h2>
<!-- <img class="close" src="./../images/address_edit_clear.png" alt=""/> -->
<canvas ref="refCanvas" :width="screenSize.width" :height="screenSize.height" :style="{opacity: 0}"></canvas>
</div>
<div class="rect" v-for="item in profile"
:style="{ width: item.width + 'px', height: item.height + 'px', left: item.left + 'px', top: item.top + 'px'}"></div>
</div>
<div v-show="!showContainer">验证成功</div>
</div>
</body>
</html>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
USER_ID: null,
screenSize: { width: window.screen.width, height: window.screen.height },
URL: null,
streamIns: null, // 视频流
showContainer: true, // 显示
tracker: null,
tipFlag: false, // 提示用户已经检测到
flag: false, // 判断是否已经拍照
context: null, // canvas上下文
profile: [], // 轮廓
removePhotoID: null, // 停止转换图片
scanTip: '人脸识别中...请将人脸置于镜头内', // 提示文字
imgUrl: '', // base64格式图片
weburl: config.weburl,
msg: '',
countdown: 0,
timer: null
},
beforeDestroy() {
if (this.timer) {
clearInterval(this.timer)
this.timer = null
}
},
mounted() {
this.USER_ID = this.getUrlKey('USER_ID')
// 这段代 主要是获取摄像头的视频流并显示在Video 签中
window.addEventListener('DOMContentLoaded', function() {
// 拍照按钮
// $("#snap").click(function () {
// context.drawImage(video, 0, 0, 330, 250);
// })
// 拍照每秒一次
// setInterval(function(){
// context.drawImage(video, 0, 0, 330, 250)
// },1000);
var constraints = { 'audio': false, 'video': { 'facingMode': 'user' }}
// 老的浏览器可能根本没有实现 mediaDevices所以我们可以先设置一个空的对象
if (navigator.mediaDevices === undefined) {
navigator.mediaDevices = {}
}
// 一些浏览器部分支持 mediaDevices。我们不能直接给对象设置 getUserMedia
// 因为这样可能会覆盖已有的属性。这里我们只会在没有getUserMedia属性的时候添加它。
if (navigator.mediaDevices.getUserMedia === undefined) {
navigator.mediaDevices.getUserMedia = function(constraints) {
// 首先如果有getUserMedia的话就获得它
var getUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia
// 一些浏览器根本没实现它 - 那么就返回一个error到promise的reject来保持一个统一的接口
if (!getUserMedia) {
return Promise.reject(new Error('getUserMedia is not implemented in this browser'))
}
// 否则为老的navigator.getUserMedia方法包裹一个Promise
return new Promise(function(resolve, reject) {
getUserMedia.call(navigator, constraints, resolve, reject)
})
}
}
if (window.stream) {
window.stream.getTracks().forEach(track => {
track.stop()
})
}
navigator.mediaDevices.getUserMedia(constraints)
.then(function(stream) {
var video = document.querySelector('video')
video.setAttribute('playsinline', true)
// 旧的浏览器可能没有srcObject
window.stream = stream
if ('srcObject' in video) {
video.srcObject = stream
} else {
// 防止在新的浏览器里使用它,应为它已经不再支持了
video.src = window.URL.createObjectURL(stream)
}
video.play()
})
.catch(function(err) {
alert(err.name + ': ' + err.message)
}) // 总是在最后检查错误
}, false)
this.tackPhoto()
},
methods: {
// 拍照
tackPhoto() {
this.context = this.$refs.refCanvas.getContext('2d') // 画布
this.timer = setInterval(() => {
this.countdown += 1
if (this.countdown > 30) {
clearInterval(this.timer)
this.timer = null
this.msg = '验证失败,请重新打开此页面'
}
this.context.drawImage(this.$refs.refVideo, 0, 0, this.screenSize.width, this.screenSize.height)
// // 保存为base64格式
this.imgUrl = this.saveAsPNG(this.$refs.refCanvas)
// /** 拿到base64格式图片之后就可以在this.compare方法中去调用后端接口比较了也可以调用getBlobBydataURI方法转化成文件再去比较
// * 我们项目里有一个设置个人头像的地方,先保存一下用户的图片,然后去拿这个图片的地址和当前拍照图片给后端接口去比较。
// * */
var _this = this
var USERAVATARURL = this.imgUrl.substring(this.imgUrl.indexOf('base64,') + 7)
$.ajax({
xhrFields: {
withCredentials: true
},
type: 'POST',
url: config.httpurl + '/app/user/compareFaceForH5',
data: {
USERAVATARURL: USERAVATARURL,
USER_ID: this.USER_ID
},
dataType: 'json',
success: function(data) {
var result = data.result
if (result == 'success') {
clearInterval(_this.timer)
_this.timer = null
_this.msg = '验证成功'
_this.showContainer = false
} else if (result == 'error') {
_this.msg = data.msg
}
},
fail: function(data) {
_this.msg = '验证失败'
}
})
// this.msg = USERAVATARURL
}, 2000)
},
// 保存为png,base64格式图片
saveAsPNG(c) {
return c.toDataURL('image/png', 0.3)
},
// 根据url参数名称获取参数值
getUrlKey: function(name) {
return decodeURIComponent(
(new RegExp('[?|&]' + name + '=' + '([^&;]+?)(&|#|;|$)').exec(location.href) || [, ''])[1].replace(/\+/g, '%20')) || null
}
}
})
</script>