0.2.5 • Published 2 years ago

@femate/web-camera v0.2.5

Weekly downloads
-
License
Apache-2.0
Repository
github
Last release
2 years ago

简介

使用文档介绍 | 博文介绍

特性

  • ✅简单、易可拓展的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

公众号:盲僧公众号,关注后回复「粉丝群」

RoadMap

Milestones

License

Apache-2.0 © MaleWeb

0.2.5

2 years ago

0.2.4

2 years ago

0.2.3

2 years ago

0.2.2

2 years ago

0.2.1

2 years ago

0.2.0

2 years ago

0.1.8

2 years ago

0.1.7

2 years ago

0.1.6

2 years ago

0.1.5

2 years ago

0.1.4

2 years ago

0.1.3

2 years ago

0.1.2

2 years ago

0.1.1

2 years ago