使用 Canvas 实现简单人脸识别交互
如果要实现一个类似人脸识别的界面,要求使用 canvas 进行绘制,中间镂空透明区域,背景是白色的画布。
技术方案:
- 首先,使用 canvas 绘制一个白色画布
- 其次,使用 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)!