一、trackingjs初体验-颜色捕获 vue3

前言

Tracking.js 是一个独立的JavaScript库(不依赖于任何框架),用于跟踪从相机实时收到的数据。
跟踪的数据既可以是颜色,也可以是人,
也就是说我们可以通过检测到某特定颜色,或者检测一个人体/脸的出现与移动,来触发JavaScript 事件。
它是非常易于使用的API,具有数个方法和事件(足够使用了)。
还有一个我觉得不错的功能就是,截取摄像头的图像,对于一些网站用这个功能来设置用户头像也是个很炫的功能。

安装

yarn add tracking
yarn add @types/tracking

使用教程

例子是vue3+ts+less
安装并引入

//@ts-nocheck

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import "tracking";
import "tracking/build/data/face";
import { Notify } from 'vant';

function getUserMedia(constrains, success, error) {
    if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
        //最新标准API
        Notify({ type: 'success', message: '支持最新标准API' });
        navigator.mediaDevices.getUserMedia(constrains).then(success).catch(error);
    } else if (navigator.webkitGetUserMedia) {
        Notify({ type: 'success', message: '支持webkit内核浏览器' });
        //webkit内核浏览器
        navigator.webkitGetUserMedia(constrains).then(success).catch(error);
    } else if (navigator.mozGetUserMedia) {
        Notify({ type: 'success', message: '支持Firefox浏览器' });
        //Firefox浏览器
        navagator.mozGetUserMedia(constrains).then(success).catch(error);
    } else if (navigator.getUserMedia) {
        Notify({ type: 'success', message: '支持旧版API' });
        //旧版API
        navigator.getUserMedia(constrains).then(success).catch(error);
    } else {
        Notify('浏览器不支持getUserMedia');
    }
}

// 要重写initUserMedia_ 方法,因为chrome的底层api已做调整
window.tracking.initUserMedia_ = function (element, opt_options) {
    const options = {
        video: true,
        audio: !!(opt_options && opt_options.audio)
    };
    getUserMedia(options, function (stream) {
        try {
            element.srcObject = stream;
        } catch (err) {
            element.src = window.URL.createObjectURL(stream);
        }
    }, function (e) {
        Notify(e.message);
    }
    );
};


// 重写视频捕获方法,因为不能停止 stop无效的bug
window.tracking.trackVideo_ = function (element, tracker) {
    console.log('trackVideo_');
    var canvas = document.createElement('canvas');
    var context = canvas.getContext('2d');
    var width;
    var height;

    var resizeCanvas_ = function () {
        width = element.offsetWidth;
        height = element.offsetHeight;
        canvas.width = width;
        canvas.height = height;
    };
    resizeCanvas_();
    element.addEventListener('resize', resizeCanvas_);

    var requestId;
    var stopped = false;
    var requestAnimationFrame_ = function () {
        requestId = window.requestAnimationFrame(function () {
            if (element.readyState === element.HAVE_ENOUGH_DATA) {
                try {
                    // Firefox v~30.0 gets confused with the video readyState firing an
                    // erroneous HAVE_ENOUGH_DATA just before HAVE_CURRENT_DATA state,
                    // hence keep trying to read it until resolved.
                    context.drawImage(element, 0, 0, width, height);
                } catch (err) { }
                tracking.trackCanvasInternal_(canvas, tracker);
            }
            if (stopped !== true) {
                requestAnimationFrame_();
            }
        });
    };
    var task = new tracking.TrackerTask(tracker);
    task.on('stop', function () {
        stopped = true;
        window.cancelAnimationFrame(requestId);
    });
    task.on('run', function () {
        stopped = false;
        requestAnimationFrame_();
    });
    return task.run();
};

createApp(App).use(router).mount('#app')
<template>
  <div class="wrapp">
    <video id="myVideo" width="800" height="500" preload="preload" autoplay loop muted src="/other/video.mp4" />
    <canvas ref="myCanvas" class="myCanvas" width="800" height="500"></canvas>
  </div>
</template>
<script setup lang="ts">
import { onMounted, ref } from 'vue';

// 标识用的画布
const myCanvas = ref<HTMLCanvasElement | null>(null);

// 实例颜色检查器
const myTracker = new tracking.ColorTracker(['yellow']);

// 监听颜色检查器
myTracker.on('track', (event: tracking.TrackEvent) => {
  const context = myCanvas.value?.getContext('2d') as CanvasRenderingContext2D;
  if (myCanvas.value) {
    context.clearRect(0, 0, myCanvas.value.width, myCanvas.value.height);
  }
  if (event.data.length === 0) {
    console.log('没有捕获到内容');
  } else {
    event.data.forEach((rect: tracking.TrackRect) => {
      const { x, y, width, height, color = 'red' } = rect;
      context.strokeStyle = color;
      context.strokeRect(x, y, width, height);
      context.font = '11px Helvetica';
      context.fillStyle = '#fff';
      context.fillText(`x:${x}px`, x + width + 5, y + 11);
      context.fillText(`y:${y}px`, x + width + 5, y + 22);
    });
  }
});

onMounted(() => {
  // 触发颜色检查器
  tracking.track('#myVideo', myTracker);
});
</script>
<style lang="less" scoped>
.wrapp {
  position: relative;
  .myCanvas {
    position: absolute;
    top: 0;
    left: 0;
  }
}
</style>

效果

补充

如果需要摄像头实时捕获,则出触发调用,option配置参数 这样即可

onMounted(() => {
  // 触发颜色检查器
  tracking.track('#myVideo', myTracker, { camera: true });
});
posted @   丁少华  阅读(2330)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示