自学内容网 自学内容网

使用 Canvas 实现简单人脸识别交互

如果要实现一个类似人脸识别的界面,要求使用 canvas 进行绘制,中间镂空透明区域,背景是白色的画布。

技术方案:

  1. 首先,使用 canvas 绘制一个白色画布
  2. 其次,使用 context.globalCompositeOperation 合成属性进行多图层处理

UI 绘制

<section>
  <video id="video-preview" width="0%" height="0%" autoPlay />
  <div>
      <canvas id="video-canvas" width="300" height="300" />
  </div>

  <button id="start-recording">start</button>
  <button id="stop-recording" disabled>
      stop
  </button>
</section>

逻辑实现(纯js实现)

// 获取 DOM 元素
const video: any = document.getElementById('video-preview');

const canvas: any = document.getElementById('video-canvas');
const ctx = canvas.getContext('2d');

// 设定遮罩区域的尺寸
const centerX = canvas.width / 2;
const centerY = canvas.height / 2;
const outerRadius = Math.min(centerX, centerY) * 0.9;

// 绘制视频帧
function drawFrame() {
    // 绘制 Video 流
    ctx.drawImage(video, 0, 0, canvas.width, canvas.height);

    ctx.beginPath();
    ctx.arc(centerX, centerY, outerRadius, 0, 2 * Math.PI);

    ctx.globalCompositeOperation = 'destination-in'; // 使用复合操作使颜色变为透明
    ctx.fill();
    // 恢复默认的混合模式
    ctx.globalCompositeOperation = 'source-over';
    // 循环绘制
    requestAnimationFrame(drawFrame);
}

const startRecordingButton: any = document.getElementById('start-recording');
const stopRecordingButton: any = document.getElementById('stop-recording');

// 录制状态标志
let isRecording: any = false;
let recordedBlobs: any = [];
let mediaRecorder: any = null;
let stream: any = null;

// 请求访问媒体设备
navigator.mediaDevices
    .getUserMedia({ video: true, audio: true })
    .then((_stream) => {
        stream = _stream;
        video.srcObject = stream; // 设置视频源
    })
    .catch((err) => console.error('Error:', err));

// 等待视频流就绪
video.addEventListener('canplay', () => {
    drawFrame();
});
// 开始录制按钮点击事件处理函数
startRecordingButton.addEventListener('click', () => {
    if (!isRecording) {
        isRecording = true;
        startRecordingButton.disabled = true;
        stopRecordingButton.disabled = false;

        recordedBlobs = [];
        mediaRecorder = new MediaRecorder(stream);
        mediaRecorder.ondataavailable = (event) => {
            if (event.data && event.data.size > 0) {
                recordedBlobs.push(event.data);
            }
        };
        mediaRecorder.onstop = () => {
            // 录制结束后,合并 Blob
            const blob = new Blob(recordedBlobs, { type: 'video/mp4' });
            const url = URL.createObjectURL(blob);
            const a = document.createElement('a');
            document.body.appendChild(a);
            a.style.display = 'none';
            a.href = url;
            a.download = 'recorded-video.mp4';
            a.click();
            window.URL.revokeObjectURL(url);
        };
        mediaRecorder.start();
    }
});

// 停止录制按钮点击事件处理函数
stopRecordingButton.addEventListener('click', () => {
    if (isRecording) {
        mediaRecorder.stop();
        isRecording = false;
        startRecordingButton.disabled = false;
        stopRecordingButton.disabled = true;
    }
});

在线查看


原文地址:https://blog.csdn.net/u013243347/article/details/144278743

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!