一、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 });
});


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM