调用手机默认的相机
- 调用
<!-- 限制只能选择图片 -->
<input type="file" accept="image/*">
<!-- 限制只能选择视频 -->
<input type="file" accept="video/*">
<!-- 限制只能选择音频 -->
<input type="file" accept="audio/*">
<!-- 直接打开摄像头拍照 -->
<input type="file" accept="image/*" capture="camera">
<!-- 直接打开摄像头录像 -->
<input type="file" accept="video/*" capture="camera">
- 渲染
绑定change事件获取上传的文件file[0]
创建FileReader对象
为这个对象绑定onload事件,文件读取完成后触发
转为图片地址,转换后的地址会在对象的result中返回(base64地址)
let reader = new FileReader();
reader.onload = ()=>{
img.src = reader.result
}
reader.readAsDataURL(file)
还可以直接使用URL.createObjectURL(file),转换地址(blob地址)
使用getUserMedia API访问媒体设备
主要是使用navigator.mediaDevices.getUserMedia这个方法,为了保险前期需要做一些处理
经测试在安卓没有问题
在ios测试结果:在微信浏览器中不支持无法使用;在Safari中每次访问都会弹出授权相机,允许后会独立视频框,所以需要视频同层播放
<video
ref="video"
id="video"
autoplay="autoplay"
preload="load"
playsinline="true"
webkit-playsinline="true"
x-webkit-airplay="allow"
airplay="allow"
x5-video-player-type="h5"
x5-video-player-fullscreen="true"
x5-video-orientation="portrait"
></video>
//老的浏览器可能没有实现 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'));
}
// 否则,为老的navigator.getUserMedia方法包裹一个Promise
return new Promise(function (resolve, reject) {
getUserMedia.call(navigator, constraints, resolve, reject);
});
}
}
//默认使用前摄像头,强制使用后置摄像头如下设置
// let constraints = {video: { facingMode: { exact: "environment" } }};
let constraints = {
video: true
};
navigator.mediaDevices.getUserMedia(constraints)
.then(function (stream) {
// 旧的浏览器可能没有srcObject
if ("srcObject" in video) {
video.srcObject = stream;
} else {
// 防止在新的浏览器里使用它,应为它已经不再支持了
video.src = window.URL.createObjectURL(stream);
}
video.onloadedmetadata = function (e) {
video.play();
};
})
.catch(function (err) {
console.log(err.name + ": " + err.message);
});
//注册拍照按钮的单击事件
document.getElementById("capture").addEventListener("click", function () {
canvas.width = video.offsetWidth
canvas.height = video.offsetHeight
//绘制画面
context.drawImage(video, 0, 0, video.offsetWidth, video.offsetHeight);
});
人脸识别
- 基础人脸识别
使用tracking.js可以帮助我们快速识别人脸
一、创建追踪对象
数组中可以写入捕获的对象,例如[“face”,“eye”,“mouth”]对应的就是脸、眼、嘴唇,记得要引入对应的文件
二、开始追踪
参数1是对应的图片标签,参数2是创建的对象
三、监听追踪
开始追踪,会把追踪到的数据返回
返回数据是一个数组,空数组就是没有识别到,识别到数据里面包含位置信息和大小信息
四、利用返回的信息创建dom元素,标出位置
//引入资源
import "../assets/js/tracking-min.js"; //这是基本文件
import "../assets/js/face-min"; //识别脸的文件,同样还有eye,mouth文件
// 创建追踪对象
let tracker = new tracking.ObjectTracker(["face"]);
//开始追踪
tracking.track("#img", tracker);
//监听追踪
tracker.on("track", (e) => {
if (e.data.length === 0) {
this.$toast("没有检测到人脸");
} else {
e.data.forEach((ele) => {
//标出位置
this.plot(ele.x, ele.y, ele.width, ele.height);
});
}
});
//利用返回的信息创建dom元素,标出位置
plot(x, y, w, h) {
let dom = document.createElement("div");
document.querySelector(".container").appendChild(dom);
dom.classList.add("rect");
dom.style.width = w + "px";
dom.style.height = h + "px";
dom.style.left = x + "px";
dom.style.top = y + "px";
},
},
tips: 我这里用的是组件进行上传,有时会出现图片被旋转90°,这样就会导致图片识别失败,这里可以借助compressorjs
对图片进行修正
- 调用摄像头识别
上面是识别图片,同样还可以调用摄像头进行动态人脸捕获,结合上面两个例子就可以实现,同样tracking也提供开启摄像头,但是感觉不好控制
//track接受第三个参数,可以调用摄像头
tracking.track("#video", tracker,{camera:true});
剩下的就是两者的结合。
更多效果请看示例:https://face-camera.vercel.app
最后:实现人脸识别的还有face-api.js,同时可以搭配百度人脸识别接口,做一些人脸登录,人脸支付等一些功能。