使用 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 = () => {// 录制结束后,合并 Blobconst 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;}
});
在线查看
点击查看
相关文章:
使用 Canvas 绘制一个镂空的圆形区域
如果要实现一个类似人脸识别的界面,要求使用 canvas 进行绘制,中间镂空透明区域,背景是白色的画布。 技术方案: 首先,使用 canvas 绘制一个白色画布其次,使用 context.globalCompositeOperation 合成属性进…...

【Notepad++】---设置背景为护眼色(豆沙绿)最新最详细
在编程的艺术世界里,代码和灵感需要寻找到最佳的交融点,才能打造出令人为之惊叹的作品。而在这座秋知叶i博客的殿堂里,我们将共同追寻这种完美结合,为未来的世界留下属于我们的独特印记。 【Notepad】---设置背景为护眼色…...

2024 数学建模国一经验分享
2024 数学建模国一经验分享 背景:武汉某211,专业:计算机科学 心血来潮,就从学习和组队两个方面指点下后来者,帮新人避坑吧 2024年我在数学建模比赛中获得了国一(教练说论文的分数是湖北省B组第一࿰…...
安全见闻2
安全见闻,犹如一座庞大而深邃的知识宝库,其中涵盖了形形色色的网络安全知识与错综复杂的网络技术体系。在当今数字化时代,这些领域的重要性不言而喻,它们不仅关乎个人信息的保护与隐私安全,更是支撑着整个互联网世界以…...
Web游戏开发指南:在 Phaser.js 中读取和管理游戏手柄输入
前言 Phaser.js 是一个广受欢迎的 HTML5 游戏框架,为开发者提供了创建跨平台 2D 游戏的强大工具。在现代游戏开发中,支持游戏手柄已成为提升玩家体验的重要方面。本文将详细介绍如何在 Phaser.js 中监听和处理游戏手柄的输入,帮助开发者为他…...

代码随想录32 动态规划理论基础,509. 斐波那契数,70. 爬楼梯,746. 使用最小花费爬楼梯。
1.动态规划理论基础 动态规划刷题大纲 什么是动态规划 动态规划,英文:Dynamic Programming,简称DP,如果某一问题有很多重叠子问题,使用动态规划是最有效的。 所以动态规划中每一个状态一定是由上一个状态推导出来的…...

记录一个Flutter 3.24单元测试点击事件bug
哈喽,我是老刘 这两天发现一个Flutter 3.24版本的单元测试的一个小bug,提醒大家注意一下。 老刘自己写代码十多年了,写Flutter也6年多了,没想到前两天在一个小小的BottomNavigationBar 组件上翻了车。 给大家分享一下事件的经过。…...
使用Python将 word文档转pdf文档
第一步:我们需要导入支持包 >pip install pywin32 如果下载速度比较慢的话,可以考虑使用国内镜像源。 第二步:我们需要导入文件,这里采用 input,用户填入路径后,直接获取路径下的word文档,实现批量转换…...

基于C#+SQLite开发数据库应用的示例
SQLite数据库,小巧但功能强大;并且是基于文件型的数据库,驱动库就是一个dll文件,有些开发工具 甚至不需要带这个dll,比如用Delphi开发,用一些三方组件;数据库也是一个文件,虽然是个文…...

Vue基本语法
Options API 选项式/配置式api 需要在script中的export default一个对象对象中可以包含data、method、components等keydata是数据,数据必须是一个方法(如果是对象,会导致多组件的时候,数据互相影响,因为对象赋值后&…...
芯片发展史
芯片的发展史可分为几个重要的阶段,从早期的真空管到现代的集成电路,反映了技术进步和创新的历程: 1. 真空管时代 (1904 - 1950年代) 真空管是20世纪初的电子元件,用于放大信号和开关,广泛应用在早期的收音机、电视机…...

我的知识图谱和Neo4j数据库的使用
知识图谱概述 知识图谱的含义 RDF与RDFS RDF(Resource Description Framework,资源描述框架)和RDFS(RDF Schema,RDF模式)是构建知识图谱的基础技术之一。它们提供了一种标准的方式来表示信息,…...

ASP.NET CORE API 解决跨域问题
环境 vs2022 .net 8 创建ASP.net Core API项目 配置跨域 编写ApiController 启动项目 得到服务器运行的 地址 在Hbuiler中创建web项目,编写代码 【运行】-【运行到浏览器】-选择一个浏览器,查看结果 正常显示 问题 如果允许所有源访问,有安全风险方…...
sram测试注意讨论
常规测试首先是mbist测试,原理不用多说,自己看,主要是注意点和考虑点: 1、明确测试用的到func_clk的频率的大小,根据经验值一般大于800M的时钟需要特别考虑Timing的问题:由于pr摆放的位置原因,…...
Mybatis 支持延迟加载的详细内容
延迟加载的概念深入 延迟加载是一种在处理复杂对象关系时非常有用的策略。在企业级应用开发中,数据库中的表之间往往存在着各种关联关系,如一对多(一个用户有多个订单)、多对多(一个学生可以选多门课程,一门…...
word文档使用技巧笔记
中文和数字断开到第二行 word一串数字断开_百度知道 下划线对齐 word下划线怎么固定长度一致-百度经验...

使用docker-compose部署搜索引擎ElasticSearch6.8.10
背景 Elasticsearch 是一个开源的分布式搜索和分析引擎,基于 Apache Lucene 构建。它被广泛用于实时数据搜索、日志分析、全文检索等应用场景。 Elasticsearch 支持高效的全文搜索,并提供了强大的聚合功能,可以处理大规模的数据集并进行快速…...

bugku-web-login2
不知道为啥用bp始终登不上hackbar可以 随便输入个账号密码bp抓包,发现个小tip是base64加密的解密 $sql"SELECT username,password FROM admin WHERE username".$username.""; if (!empty($row) && $row[password]md5($password)){ } …...

【 AI技术赋能有限元分析与材料科学应用实践】Neo-Hookean 材料与深度学习结合的有限元分析
Neo-Hookean 材料模型是用于描述非线性弹性材料(如软组织和橡胶等)的经典模型,特别适用于大变形问题。其基本思想是通过应变能密度函数来描述材料的弹性行为。在该模型中,材料的应力-应变关系不仅依赖于应变能,还通过变…...
StarRocks关于ConcurrentModificationException 问题的解决
背景 本文基于 StarRocks 3.1.7 目前在基于Starrocks做一些数据分析的操作(主要是做一些简单的查询),同事遇到了一些并发的问题: ontent:2024-11-27 07:04:34,048 WARN (starrocks-mysql-nio-pool-214933|3593819) [StmtExecutor.execute():643] execute Exceptio…...

多模态2025:技术路线“神仙打架”,视频生成冲上云霄
文|魏琳华 编|王一粟 一场大会,聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中,汇集了学界、创业公司和大厂等三方的热门选手,关于多模态的集中讨论达到了前所未有的热度。其中,…...
1688商品列表API与其他数据源的对接思路
将1688商品列表API与其他数据源对接时,需结合业务场景设计数据流转链路,重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点: 一、核心对接场景与目标 商品数据同步 场景:将1688商品信息…...
React Native在HarmonyOS 5.0阅读类应用开发中的实践
一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强,React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 (1)使用React Native…...

令牌桶 滑动窗口->限流 分布式信号量->限并发的原理 lua脚本分析介绍
文章目录 前言限流限制并发的实际理解限流令牌桶代码实现结果分析令牌桶lua的模拟实现原理总结: 滑动窗口代码实现结果分析lua脚本原理解析 限并发分布式信号量代码实现结果分析lua脚本实现原理 双注解去实现限流 并发结果分析: 实际业务去理解体会统一注…...
【Java学习笔记】BigInteger 和 BigDecimal 类
BigInteger 和 BigDecimal 类 二者共有的常见方法 方法功能add加subtract减multiply乘divide除 注意点:传参类型必须是类对象 一、BigInteger 1. 作用:适合保存比较大的整型数 2. 使用说明 创建BigInteger对象 传入字符串 3. 代码示例 import j…...

LINUX 69 FTP 客服管理系统 man 5 /etc/vsftpd/vsftpd.conf
FTP 客服管理系统 实现kefu123登录,不允许匿名访问,kefu只能访问/data/kefu目录,不能查看其他目录 创建账号密码 useradd kefu echo 123|passwd -stdin kefu [rootcode caozx26420]# echo 123|passwd --stdin kefu 更改用户 kefu 的密码…...

使用LangGraph和LangSmith构建多智能体人工智能系统
现在,通过组合几个较小的子智能体来创建一个强大的人工智能智能体正成为一种趋势。但这也带来了一些挑战,比如减少幻觉、管理对话流程、在测试期间留意智能体的工作方式、允许人工介入以及评估其性能。你需要进行大量的反复试验。 在这篇博客〔原作者&a…...

【从零学习JVM|第三篇】类的生命周期(高频面试题)
前言: 在Java编程中,类的生命周期是指类从被加载到内存中开始,到被卸载出内存为止的整个过程。了解类的生命周期对于理解Java程序的运行机制以及性能优化非常重要。本文会深入探寻类的生命周期,让读者对此有深刻印象。 目录 …...

GO协程(Goroutine)问题总结
在使用Go语言来编写代码时,遇到的一些问题总结一下 [参考文档]:https://www.topgoer.com/%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/goroutine.html 1. main()函数默认的Goroutine 场景再现: 今天在看到这个教程的时候,在自己的电…...

pikachu靶场通关笔记19 SQL注入02-字符型注入(GET)
目录 一、SQL注入 二、字符型SQL注入 三、字符型注入与数字型注入 四、源码分析 五、渗透实战 1、渗透准备 2、SQL注入探测 (1)输入单引号 (2)万能注入语句 3、获取回显列orderby 4、获取数据库名database 5、获取表名…...