基于vue实现人脸识别组件
1.安装依赖npm install tracking2.封装组件<template><div class="camera_outer"><!--此处代码请勿随意删除:input兼容ios无法调用摄像头的问题accept属性兼容某些华为手机调用摄像头,打开的是文件管理器的问题--><inputtype="file"id="file"accep
·
1.安装依赖
npm install tracking
2.封装组件
<template>
<div class="camera_outer">
<!--
此处代码请勿随意删除:
input兼容ios无法调用摄像头的问题
accept属性兼容某些华为手机调用摄像头,打开的是文件管理器的问题
-->
<input
type="file"
id="file"
accept="image/*"
capture="camera"
style="display:none"
@change="changePic"
/>
<video
id="videoCamera"
:width="videoWidth"
:height="videoHeight"
autoplay
class="img_bg_camera"
/>
<canvas
style="display:none"
id="canvasCamera"
:width="videoWidth"
:height="videoHeight"
class="img_bg_camera"
/>
<div v-if="imgSrc" class="img_bg_camera" :class="[isDisplay?'displayBlock':'displayNone']">
<img :src="imgSrc" alt class="tx_img" />
</div>
<div class="bottomButton">
<van-button color="#aaaaaa" @click="goBack()" class="marginRight10">返回</van-button>
<van-button type="warning" @click="getCamers()" class="marginRight10">打开摄像机</van-button>
<van-button type="warning" @click="setImage()">拍照</van-button>
</div>
</div>
</template>
<script lang="ts">
import { Component, Vue, Emit } from "vue-property-decorator";
import { Toast } from "vant";
require("../common/js/tracking-min");
require("../common/js/face-min");
require("../common/js/mouth-min");
require("../common/js/stats.min.js");
@Component
export default class faceRecognition extends Vue {
private videoWidth: number = 300; //摄像机宽度
private videoHeight: number = 300; //摄像机高度
private imgSrc: string = ""; //生成图片链接
private thisCanvas: any = null; //canvas
private thisContext: any = null; //context
private thisVideo: any = null; //video
private isFlag: boolean = false; //非正常拍照
private isDisplay: boolean = false; //生成的照片是否显示
//调用权限(打开摄像头功能)
getCompetence() {
var _this = this;
//得到canvasCamera的元素
this.thisCanvas = document.getElementById("canvasCamera");
this.thisContext = this.thisCanvas.getContext("2d");
this.thisVideo = document.getElementById("videoCamera") as
| HTMLImageElement
| SVGImageElement
| HTMLVideoElement
| HTMLCanvasElement
| ImageBitmap
| OffscreenCanvas;
// 旧版本浏览器可能根本不支持mediaDevices,我们首先设置一个空对象
if (navigator.mediaDevices === undefined) {
Object.defineProperty(navigator, "mediaDevices", {
value: {},
writable: true,
configurable: true,
enumerable: true,
});
}
// 一些浏览器实现了部分mediaDevices,我们不能只分配一个对象,如果使用getUserMedia,因为它会覆盖现有的属性。如果缺少getUserMedia属性,就添加它。
if (navigator.mediaDevices.getUserMedia === undefined) {
navigator.mediaDevices.getUserMedia = function (constraints) {
// 首先获取现存的getUserMedia(如果存在)
var getUserMedia =
navigator.getUserMedia || navigator.mediaDevices.getUserMedia;
// 有些浏览器不支持,会返回错误信息
if (!getUserMedia) {
Toast("getUserMedia is not implemented in this browser");
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 as any, resolve, reject);
});
};
}
var constraints = {
audio: false,
video: {
width: this.videoWidth,
height: this.videoHeight,
transform: "scaleX(-1)",
},
};
//使苹果手机和苹果ipad支持打开摄像机
if (
(navigator.userAgent.toLowerCase().indexOf("iphone") != -1 ||
navigator.userAgent.toLowerCase().indexOf("ipad") != -1)
) {
//使得file一定可以获取到
document.getElementById("file")!.click();
} else {
//在用户允许的情况下,打开相机,得到相关的流
navigator.mediaDevices
.getUserMedia(constraints)
.then(function (stream) {
// 旧的浏览器可能没有srcObject
if (!_this.thisVideo) {
_this.thisVideo = {};
}
try {
_this.thisVideo.srcObject = stream;
} catch (err) {
_this.thisVideo.src = window.URL.createObjectURL(stream);
}
_this.isFlag = true;
_this.thisVideo.onloadedmetadata = () => _this.thisVideo.play();
})
.catch((err) => {
Toast(err);
console.log(err);
});
}
}
//苹果手机获取图片并且保存图片
changePic() {
var reader = new FileReader();
var f = (document.getElementById("file") as HTMLInputElement)
.files as FileList;
reader.readAsDataURL(f[0]);
reader.onload = () => {
var re = reader.result as string;
this.canvasDataURL(re, { quality: 0.3 }, (base64Codes: string) => {
if (base64Codes) {
this.imgSrc = base64Codes;
this.isDisplay = true;
this.submitCollectInfo();
} else {
Toast("拍照失败");
}
});
};
}
//压缩图片
canvasDataURL(path: string, obj: any, callback: any) {
let img = new Image();
img.src = path;
img.onload = () => {
let that: any = this;
// 默认按比例压缩
var w: any = that.videoWidth,
h: any = that.videoHeight,
scale = w / h;
w = obj.width || w;
h = obj.height || w / scale;
var quality = 0.5; // 默认图片质量为0.5
//生成canvas
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
// 创建属性节点
ctx!.drawImage(image, 0, 0, w, h);
// 图像质量
if (obj.quality && obj.quality <= 1 && obj.quality > 0) {
quality = obj.quality;
}
// quality值越小,所绘制出的图像越模糊
var base64 = canvas.toDataURL("image/jpeg", quality);
// 回调函数返回base64的值
callback(base64);
};
}
//绘制图片(拍照功能)
setImage() {
this.thisContext.drawImage(
this.thisVideo as
| HTMLImageElement
| SVGImageElement
| HTMLVideoElement
| HTMLCanvasElement
| ImageBitmap
| OffscreenCanvas,
0,
0,
this.videoWidth,
this.videoHeight
);
// 获取图片base64链接
var image = this.thisCanvas.toDataURL("image/png", 0.5);
if (this.isFlag) {
if (image) {
this.imgSrc = image;
this.isDisplay = true;
this.submitCollectInfo();
} else {
Toast("拍照失败");
}
} else {
Toast("拍照失败");
}
}
//保存图片
async submitCollectInfo() {
//其中可以和后端做一些交互
}
// 关闭摄像头
stopNavigator() {
if (this.thisVideo.srcObject) {
this.thisVideo.srcObject.getTracks()[0].stop();
}
}
//打开摄像机
getCamers() {
this.isDisplay = false;
}
//返回
goBack() {
this.stopNavigator();
//可以写相应的返回的一些操作,携带一些需要携带的参数
}
mounted() {
this.getCompetence();
}
destory() {
this.stopNavigator();
}
}
</script>
<style lang="scss" scoped>
.camera_outer {
position: relative;
overflow: hidden;
background-size: cover;
background: white;
width: 100%;
height: 100%;
}
video,
canvas,
.tx_img {
-moz-transform: scaleX(-1);
-webkit-transform: scaleX(-1);
-ms-transform: scaleX(-1);
-o-transform: scaleX(-1);
transform: scaleX(-1);
}
.img_bg_camera {
position: absolute;
bottom: 25%;
top: 25%;
left: 50%;
margin-left: -150px;
border-radius: 50%;
-webkit-border-radius: 50%;
-moz-border-radius: 50%;
-ms-border-radius: 50%;
-o-border-radius: 50%;
}
.img_bg_camera img {
width: 300px;
height: 300px;
border-radius: 50%;
-webkit-border-radius: 50%;
-moz-border-radius: 50%;
-ms-border-radius: 50%;
-o-border-radius: 50%;
}
.displayNone {
display: none;
}
.displayBlock {
display: block;
}
.marginRight10 {
margin-right: 20px;
}
.bottomButton {
position: fixed;
bottom: 20px;
width: 100%;
text-align: center;
}
</style>
更多推荐
已为社区贡献1条内容
所有评论(0)