@femate/web-camera
v0.2.5
Published
全网最强TS版人脸识别插件
Downloads
3
Readme
简介
特性
- ✅简单、易可拓展的API,零成本上手
- ✅三种相机模式:默认相机、美颜相机、本地人脸识别相机
- ✅支持镜像:可以水平翻转。PS:保存后的图片URL根据场景翻转
- ✅支持拍照功能:根据业务场景调用即可。
- ✅支持下载图片:插件自封装a标签,触发下载事件。PS:下载的图片为拍照时记录图片。
- ✅更多能力等你挖掘....
如果您觉得这个项目还不错, 可以在 Github 上面帮我点个star
, 支持一下作者 ☜(゚ヮ゚☜)
如何使用
方式1:通过 script 标签引入
CDN源
CDN源:jsdelivr
<script src="https://cdn.jsdelivr.net/npm/@femate/web-camera@latest"></script>
CDN源:unpkg
<script src="https://unpkg.com/@femate/gweb-camera@latest"></script>
HTML调用
<h1 align="center">Hello 我是扫地盲僧!</h1>
<p align="center">这是一个兼容移动PC,实现客户端人脸识别,全网唯一TS版Web摄像头插件</p>
<div id="wrapper"></div>
<script type="text/javascript">
window.onload = () => {
const camera = new WebCamera('#wrapper', {
// 任意参数大于0,则代表开启美颜插件
beautyConfig: {
beauty: 0,
brightness: 0,
ruddy: 0
},
// 本地人脸识别插件
isClintFace: false,
takePhoto(src) {
console.log(src, '拍照的图片')
},
isHasFace(val) {
console.log('检测到人脸')
}
});
camera.start();
}
</script>
方式2:通过 import 引入
安装依赖
npm i @femate/web-camera
# or
pnpm add @femate/web-camera
# or
yarn add @femate/web-camera
使用
<h1 align="center">Hello 我是扫地盲僧!</h1>
<p align="center">这是一个兼容移动PC,实现客户端人脸识别,全网唯一TS版Web摄像头插件</p>
<div id="wrapper"></div>
import WebCamera from '@femate/web-camera'
const WebCam = new WebCamera('#app', {
// 任意参数大于0,则代表开启美颜插件
beautyConfig: {
beauty: 0,
brightness: 0,
ruddy: 0
},
// 本地人脸识别插件
isClintFace: false,
takePhoto(src) {
console.log(src, '拍照的图片')
},
isHasFace(val) {
console.log('检测到人脸')
}
})
WebCam.start()
事件
Options
const defaultOptions = {
// 相机参数
cameraStyle: {
width: 320,
height: 320,
radius: '48%',
border: '2px solid #ccc',
bg: 'black'
},
// 导出图片设置
outImg: {
// 导出图片类型,/png|jpeg|bmp|gif/
type: 'png',
// 导出图片质量0-1之间
quality: 0
},
// 是否开启镜像,响应式参数
isFlip: true,
// 美颜相机参数
beautyConfig: {
beauty: 0,
brightness: 0,
ruddy: 0
},
// 是否开启clint人脸检测
isClintFace: false,
} as const
PublicEvent
对外暴露事件
//开始视频 自动检测相机模式
public start(){...}
//拍照 PS:返回base64URL
public takePhoto(callback):string{...}
//清除画布
public clearCanvas() {...}
//手动更新美颜参数
public setBeautyParam(params:BeautyConfig){...}
//保存图片
public downloadImg(){...}
//上传图片,处理为文件格式
public uploadImg(callback){...}
//重置相机
public reset(){...}
//销毁实例
public destroy() {...}
核心code
如果你不需要过多的插件,只想要基础版设备调用事件,这里已帮你抽离出最核心的部分。
设备兼容
// 设备兼容处理兼容
const cameraPolyFill = ():Promise=>{
const URL = window.URL || window.webkitURL
this.userMedia = this.userMedia && !!navigator.mediaDevices.getUserMedia && !!this.URL
if (typeof window === 'undefined') {
return;
}
if (navigator.mediaDevices === undefined) {
navigator.mediaDevices = {};
}
// 兼容火狐不工作的情况
if (navigator.userAgent.match(/Firefox\D+(\d+)/)) {
if (parseInt(RegExp.$1, 10) < 21) this.userMedia = false;
}
// 兼容离开页面时关闭媒体流
if (this.userMedia||window.stream) {
window.addEventListener('beforeunload', function (event) {
window.stream.getTracks().forEach((track: any) => {
track.stop();
});
});
}
// 如果缺少 getUserMedia 属性,我们将添加它
if (navigator.mediaDevices.getUserMedia === undefined) {
// https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia
navigator.mediaDevices.getUserMedia = function (constraints) {
const getUserMedia =
navigator.getUserMedia ||
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia ||
navigator.msGetUserMedia;
if (!getUserMedia) {
return Promise.reject(
new Error("getUserMedia is not implemented in this browser")
);
}
// 打包一个旧的 getUserMedia 函数
return new Promise(function (resolve, reject) {
getUserMedia.call(navigator, constraints, resolve, reject);
});
};
}
}
设备调用
public getUserMedia(width: number, height: number): Promise<any> {
let self = this
const constraints: ContainTypes = {
audio: false,
video: {
width: { ideal: width },
height: { ideal: height },
},
facingMode: this.front ? 'user' : 'environment',
}
return new Promise((resolve, reject) => {
navigator.mediaDevices.getUserMedia(constraints).
then((stream) => {
// 兼容异步加载问题
if ("srcObject" in this.video) {
self.video.srcObject = stream;
} else {
// 使用 URL.createObjectURL作为旧浏览器的兼容
self.video.src = self.URL.createObjectURL(stream)
}
window.stream = stream;
resolve(stream)
}).catch((error: Error) => {
reject(error);
console.log(error);
});
})
}
Video转Canvas
常规方案是toDataURL,但其性能问题我们要废弃它,1同步堵塞,2占用更多内存,3获得字符体积大等问题
public videoToCanBlob(canvas: HTMLCanvasElement, imgType: string, quality: number):Promise<any> {
return new Promise((resolve, reject) => {
//异步执行函数
const ctx = canvas.getContext('2d');
ctx?.drawImage(this.video, 0, 0, canvas.width, canvas.height)
const reader = new FileReader()
canvas.toBlob((blob: any) => {
reader.readAsDataURL(blob as any)
reader.onload = (e: any) => {
resolve(e.target?.result)
}
}, `images/${imgType}`, quality)
})
}
About Me
公众号:盲僧公众号,关注后回复「粉丝群」