Html5调用摄像头拍照,ArcSort头像识别。
背景: 用户需要统一采集头像传入系统,利用ArcSort识别头像知道绑定的用户,完成后续业务。
使用相关:HTML,JS,Spring Boot/Cloud,HttpClient。
项目结构:
index.js
/**
* 拍照上传图片
*/
var indexObj = {};
indexObj.tips = "没有检测到设备,请确保开启摄像头。";
//访问用户媒体设备的兼容方法
function getUserMedia(constraints, success, error) {
if (navigator.mediaDevices.getUserMedia) {
//最新的标准API
navigator.mediaDevices.getUserMedia(constraints).then(success).catch(error);
} else if (navigator.webkitGetUserMedia) {
//webkit核心浏览器
navigator.webkitGetUserMedia(constraints, success, error)
} else if (navigator.mozGetUserMedia) {
//firfox浏览器
navigator.mozGetUserMedia(constraints, success, error);
} else if (navigator.getUserMedia) {
//旧版API
navigator.getUserMedia(constraints, success, error);
}
}
var video = document.getElementById('index__video');
function success(stream) {
//兼容webkit核心浏览器
var CompatibleURL = window.URL || window.webkitURL;
//将视频流设置为video元素的源
video.srcObject = stream;
// video.play();
video.onloadedmetadata = function (e) {
video.play();
};
}
function error(error) {
console.log("The following error occurred: ");
document.getElementById("index__tips").innerHTML = indexObj.tips;
}
// 列出摄像头和麦克风
var exArray = [];
navigator.mediaDevices.enumerateDevices().then(function (devices) {
devices.forEach(function (device) {
console.log(device.kind + ": " + device.label +
" id = " + device.deviceId);
if (device.kind == "videoinput") {
alert(device.label);
exArray.push(device.deviceId);
}
});
var mediaOpts = {video: {deviceId: {exact: exArray[1]}}};
//调用用户媒体设备, 访问摄像头
getUserMedia(mediaOpts, success, error);
}).catch(function (err) {
console.log(err.name + ": " + err.message);
});
/**
* 拍照上传按钮的事件响应
*/
indexObj.uploadImg = function () {
alert(12);
var canvas = document.getElementById("index__canvas");
var video = document.getElementById("index__video");
if (0 == video.videoWidth) {
document.getElementById("index__tips").innerHTML = indexObj.tips;
return;
}
// 让canvas和视频一样宽高。
var w = video.videoWidth;
var h = video.videoHeight;
canvas.width = w;
canvas.height = h;
// 把video标签中的画面,画到canvas中。
var ctx = canvas.getContext('2d');
ctx.drawImage(video, 0, 0, w, h);
// 把canvas中的图像转换成png图片文件的Base64字符串。
var imgStr = canvas.toDataURL('image/png').split("base64,")[1];
// 获得用户ID
var userId = document.getElementById("index__user-id").value;
axios.post("/api/profile/upload", {"userId": userId, "imgStr": imgStr}).then(function (res) {
console.log(res);
alert("上传成功")
}).catch(function (error) {
alert("上传异常!")
console.error(error);
})
}
index.html
<head>
<meta charset="UTF-8"/>
<title>拍照上传</title>
<link href="styles/index.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<div class="index__tips" id="index__tips"></div>
<div class="index__title">请将您的脸部正面放置于下方提示区域,并点击“拍照”按钮。</div>
<div class="index__video-panel">
<!-- 显示摄像头拍摄到的视频 -->
<video id="index__video" class="index__video"></video>
<!-- 视频上的提示框 -->
<svg width="200" height="200" class="index__video-over">
<!-- 克莱因蓝 #002FA7 -->
<polyline points="5,50 5,5 50,5" fill-opacity="0"
style="stroke:#002FA7;stroke-width:10"/>
<polyline points="5,150 5,195 50,195" fill-opacity="0"
style="stroke:#002FA7;stroke-width:10"/>
<polyline points="155,5 195,5 195,45" fill-opacity="0"
style="stroke:#002FA7;stroke-width:10"/>
<polyline points="155,195 195,195 195,155" fill-opacity="0"
style="stroke:#002FA7;stroke-width:10"/>
</svg>
<!-- 视频上的拍照按钮 -->
<div class="index__video-over-button" onclick="indexObj.uploadImg()">拍照并上传</div>
</div>
<!-- 用户ID -->
<input type="hidden" value="1" id="index__user-id"/>
<!-- 用于给video标签截图的画布 -->
<canvas id="index__canvas" style="display:none;"></canvas>
<script src="styles/axios.min.js"></script>
<script src="styles/index.js"></script>
</body>
</html>
其他文件由百度网盘提取:
1、仅有前端,可以直接在浏览器预览:链接:https://pan.baidu.com/s/1W_y6OpoFRAHTSFlEEujelA 提取码:t92i
2、较全的代码:
链接:https://pan.baidu.com/s/1UfwWgkOUnlGrHLYBw-GxAA
提取码:klm0
注意: 项目部署服务器端后,Html 是无法在客户端打开摄像头滴
,此时有两个解决办法:
方法一、对.jar包做签名认证(这种结果估计对大多人来说是最想要,但也是最无法接受的各种麻烦,看看方法二)。
方法二、谷歌浏览器右击—>目标后面加上--unsafely-treat-insecure-origin-as-secure="http://192.168.1.107:8080/webCam"
,(注意前面的空格,“此处是项目地址”)。