canvas实现图片标注,绘制区域
使用canvas绘制通过多边形标注区域
AI视频项目中需要分析图片,需要前台绘制区域,后端获取坐标然后识别图像,通过canvas
获取点然后连线绘图
HEML代码段
<div class="areaDrawing"><img src="@/assets/images/snapPhotos.png" /><canvas ref="canvas" style="position: absolute; top: 0; left: 0;" :width="canvasWidth":height="canvasHeight"></canvas></div>
CSS代码段
.areaDrawing {position: relative;width: 400px; // 绘图区域宽度height: 300px; // 绘图区域高度img {position: absolute;top: 0;left: 0;height: 100%;width: 100%;}
}
script代码段
<script>
// 脚本开始
export default {data() {return {canvasWidth: 400, // 画布的宽度canvasHeight: 300, // 画布的高度imageSrc: 'your_image_url_here', // 图像的URL地址context: null, // 画布上下文points: [], // 用于存储点的数组isDragging: false, // 是否正在拖拽draggingIndex: -1, // 当前拖拽的点的索引Drawing: false,//控制绘制};},methods: {// 处理点击事件,用于添加新点handleCanvasClick(event) {console.log(this.points.length, 'this.points.length');// 检查是否开启绘制if (!this.Drawing || this.points.length >= 4) {return;}// 获取点击点的坐标const rect = this.$refs.canvas.getBoundingClientRect();const x = event.clientX - rect.left;const y = event.clientY - rect.top;// 检查是否有重复点const isDuplicate = this.points.some(point => {return Math.abs(point.x - x) < 5 && Math.abs(point.y - y) < 5;});// 如果没有重复点,则添加新点并重新绘制if (!isDuplicate) {this.points.push({ x, y });this.redraw();}// 如果点的数量大于等于4个,则绘制多边形if (this.points.length >= 4) {this.drawPolygon(this.points);}},// 处理鼠标按下事件handleMouseDown(event) {if (this.Drawing) {return}// 获取鼠标按下点的坐标const rect = this.$refs.canvas.getBoundingClientRect();const x = event.clientX - rect.left;const y = event.clientY - rect.top;// 查找当前拖拽的点的索引this.draggingIndex = this.points.findIndex(point => {return Math.abs(point.x - x) < 5 && Math.abs(point.y - y) < 5;});// 如果存在拖拽的点,则设置拖拽状态为trueif (this.draggingIndex !== -1) {this.isDragging = true;}},// 处理鼠标移动事件handleMouseMove(event) {// 如果正在拖拽,则更新当前拖拽点的坐标并重新绘制if (this.isDragging) {const rect = this.$refs.canvas.getBoundingClientRect();const x = event.clientX - rect.left;const y = event.clientY - rect.top;this.points[this.draggingIndex].x = x;this.points[this.draggingIndex].y = y;this.redraw();}},// 处理鼠标释放事件handleMouseUp() {// 重置拖拽状态和拖拽点的索引this.isDragging = false;this.draggingIndex = -1;},// 绘制点drawPoint(x, y) {this.context.beginPath();this.context.arc(x, y, 5, 0, 2 * Math.PI, false);this.context.fillStyle = 'blue';this.context.fill();this.context.lineWidth = 1;this.context.strokeStyle = 'blue';this.context.stroke();},// 重新绘制画布redraw() {// 清空画布this.context.clearRect(0, 0, this.canvasWidth, this.canvasHeight);// 绘制多边形this.drawPolygon(this.points);// 绘制所有点,并连接相邻点this.points.forEach((point, index) => {this.drawPoint(point.x, point.y);if (index > 0) {this.context.beginPath();this.context.moveTo(this.points[index - 1].x, this.points[index - 1].y);this.context.lineTo(point.x, point.y);this.context.strokeStyle = 'blue';this.context.lineWidth = 1;this.context.stroke();}});// 连接第一个点和最后一个点,形成闭合的多边形if (this.points.length > 3) {this.context.beginPath();this.context.moveTo(this.points[this.points.length - 1].x, this.points[this.points.length - 1].y);this.context.lineTo(this.points[0].x, this.points[0].y);this.context.strokeStyle = 'blue';this.context.lineWidth = 1;this.context.stroke();}},// 绘制多边形drawPolygon(points) {if (points.length >= 2) {this.context.beginPath();this.context.moveTo(points[0].x, points[0].y);for (let i = 1; i < points.length; i++) {this.context.lineTo(points[i].x, points[i].y);}if (points.length === 4) {this.context.closePath();this.context.strokeStyle = 'red';this.context.lineWidth = 2;this.context.stroke();}}},// 动画方法,用于拖拽时重新绘制画布animate() {if (this.isDragging) {this.redraw();requestAnimationFrame(this.animate);}},//开始绘制handleDrawing() {this.Drawing = true;},//绘制微调resetDrawing() {this.Drawing = false;},//清除绘制clearDrawing() {this.points.length = 0;this.redraw()},},mounted() {// 获取画布上下文this.context = this.$refs.canvas.getContext('2d');// 添加事件监听器this.$refs.canvas.addEventListener('click', this.handleCanvasClick);this.$refs.canvas.addEventListener('mousedown', this.handleMouseDown);this.$refs.canvas.addEventListener('mousemove', this.handleMouseMove);this.$refs.canvas.addEventListener('mouseup', this.handleMouseUp);this.$refs.canvas.addEventListener('mouseleave', this.handleMouseUp);// 绑定动画方法的上下文this.animate = this.animate.bind(this);},
};
// 脚本结束
</script>
相关文章:
canvas实现图片标注,绘制区域
使用canvas绘制通过多边形标注区域 AI视频项目中需要分析图片,需要前台绘制区域,后端获取坐标然后识别图像,通过canvas 获取点然后连线绘图 HEML代码段 <div class"areaDrawing"><img src"/assets/images/snapPhotos…...

SELECT COUNT(*) 会造成全表扫描吗?
前言 SELECT COUNT(*)会不会导致全表扫描引起慢查询呢? SELECT COUNT(*) FROM SomeTable 网上有一种说法,针对无 where_clause 的 COUNT(*),MySQL 是有优化的,优化器会选择成本最小的辅助索引查询计数,其实反而性能…...
python考前复习(90题)
文章目录 1.Python特性的是( )。 A. 面向对象 B. 高可移植性 C. 开源、免费 2.临时改变Python语言安装源应当使用的选项是 –index-url 3.Python脚本文件的扩展名为( ) .py 4.安装Python语言的软件包使用的命令是( ) pip install 5 . (单选题)以下哪项是…...

根据SpringBoot Guides完成进行示例学习(详细步骤)
目录 1.打开Spring | Guides官网,或者直接搜索springboot都可 2.选择要学习的内容 3.根据提示的网址,Git到本地 4.将文件用IDEA打开,根据教程完成示例,这里不做细致讲解 5.运行项目 6.在终端查看运行结果 以Scheduling Task…...

waf、yakit和ssh免密登录
WAF安全狗 脏数据适用于所有漏洞绕过waf,但是前提条件垃圾信息必须放在危险信息前,是不能打断原有数据包的结构,不能影响后端对数据包的解析。 以DVWA靶场文件上传为例 新建php文件 上传文件被安全狗拦截 使用bp抓包查看 在数据包Content-…...

【AIGC核心技术剖析】大型语言和视觉助手——LLaVA(论文+源码)
🔥 [新!LLaVA-1.5 在 11 个基准测试上实现了 SoTA,只需对原始 LLaVA 进行简单的修改,利用所有公共数据,在单个 1-A8 节点上在 ~100 天内完成训练,并超越使用数十亿级数据的方法。 LLaVA代表了一种新颖的端到端训练大型多模态模型,结合了视觉编码器和骆马 对于通用的视…...
IBM的WAS简介与基本使用手册
IBM的WAS简介与基本使用手册 1. 基本介绍 WebSphereApplication Server(简称WAS)是IBM的应用服务器 基本结构:单元(cell) ——> 多个节点(node) ——> 多个服务(server) ——> 多个应用(app) 单元是整个分布式网络中一个或多个节点的逻辑分组单元是一个配置概念, 是…...

Deno 快速入门
目录 1、简介 2、安装Deno MacOS下安装 Windows下安装 Linux 下安装 3、创建并运行TypeScript程序 4、内置Web API和Deno命名空间 5、运行时安全 6、导入JavaScript模块 7、远程模块和Deno标准库 8、使用deno.json配置您的项目 9、Node.js API和npm包 10、配置IDE…...

【计算机网络笔记】OSI参考模型基本概念
系列文章目录 什么是计算机网络? 什么是网络协议? 计算机网络的结构 数据交换之电路交换 数据交换之报文交换和分组交换 分组交换 vs 电路交换 计算机网络性能(1)——速率、带宽、延迟 计算机网络性能(2)…...
ConnectTimeout和ReadTimeout所代表的意义
ConnectTimeout和ReadTimeout所代表的意义 ConnectTimeout 指的是建立连接所用的时间,适用于网络状况正常的情况下,两端连接所用的时间。在java中,网络状况正常的情况下,例如使用HttpClient或者HttpURLConnetion连接时设置参数c…...
使用Python计算平面多边形间最短距离,数据需要从excel表格中导入
使用Python计算平面多边形间最短距离,数据需要从excel表格中导入, * 多边形种类包括(圆形、矩形、六边形、五边形、跑道形/胶囊形), * Python代码需要使用gjk算法进行判断两个多边形间是否重叠, * 如果未重…...

华为数通方向HCIP-DataCom H12-831题库(多选题:1-20)
第01题 如图所示,路由器所有的接口开启OSPF,图中标识的ip地址为设备的Loopback0接口的IP地址,R1、R2,R3的Loopback0通告在区域1,R4的Loopback0通告在区域0、R5的Lopback0通告在区域2,下列哪些IP地址之间可以相互Ping通? A、10.0.3.3和10.0.5.5 B、10.0.4.4和10.0.2.2 …...

CCC数字钥匙设计【NFC】--通过NFC进行车主配对Phase3
1、车主配对流程介绍 车主配对可以通过车内NFC进行,若支持UWB测距,也可以通过蓝牙/UWB进行。通过NFC进行车主配对总共有5个Phase。本文档主要对Phase3进行介绍。 1) Phase0:准备阶段; 2) Phase1:启动流程࿱…...

开源OA协同办公系统,集成Flowable流程引擎 可拖拽创建个性表单
源码下载:https://download.csdn.net/download/m0_66047725/88403340 源码下载2: 关注我留言 开源OA协同办公系统,集成Flowable流程引擎 可拖拽创建个性表单。基于RuoYi-VUE版本开发。 1、使用RuoYi-Vue的基础上开发。 2、集成flowable&a…...

为什么嵌入通常优于TF-IDF:探索NLP的力量
塔曼纳 一、说明 自然语言处理(NLP)是计算机科学的一个领域,涉及人类语言的处理和分析。它用于各种应用程序,例如聊天机器人、情绪分析、语音识别等。NLP 中的重要任务之一是文本分类,我们根据文本的内容将文本分类为不…...

oracle-AWR报告生成方法
AWR报告生成方法 1. 以oracle用户登陆服务器 2. 进入到要保存awr报告的目录 3. 以sysdba身份连接数据库 sqlplus / as sysdba4. 执行生成AWR报告命令 ?/rdbms/admin/awrrpt.sql5. 选择AWR报告的文件格式 6. 选择生成多少天的AWR报告 7. 选择报告的快照起始和结束ID 8. 输入生…...
笙默考试管理系统-MyExamTest----codemirror(37)
笙默考试管理系统-MyExamTest----codemirror(36) 目录 一、 笙默考试管理系统-MyExamTest 二、 笙默考试管理系统-MyExamTest 三、 笙默考试管理系统-MyExamTest 四、 笙默考试管理系统-MyExamTest 五、 笙默考试管理系统-MyExamTest 笙默考试…...

【Unity3D编辑器拓展】Unity3D的IMGUI、GUI、GUILayout、EditorGUI、EditorGUILayout、OnGUI【全面总结】
推荐阅读 CSDN主页GitHub开源地址Unity3D插件分享简书地址我的个人博客 大家好,我是佛系工程师☆恬静的小魔龙☆,不定时更新Unity开发技巧,觉得有用记得一键三连哦。 一、前言 在开发中,常常会遇到要使用OnGUI的地方。 也会遇到…...

11. 机器学习 - 评价指标2
文章目录 混淆矩阵F-scoreAUC-ROC 更多内容: 茶桁的AI秘籍 Hi, 你好。我是茶桁。 上一节课,咱们讲到了评测指标,并且在文章的最后提到了一个矩阵,我们就从这里开始。 混淆矩阵 在我们实际的工作中,会有一个矩阵&am…...

Nginx的代理和负载均衡
一、nginx的代理方式 1.1 七层代理 七层代理:基于http协议,对请求的内容进行处理,然后转发到后端服务器 七层代理是客户端请求代理服务器,由代理服务器转发客户端的http请求,转发到内部的服务器进行处理(服务器可以是…...
SkyWalking 10.2.0 SWCK 配置过程
SkyWalking 10.2.0 & SWCK 配置过程 skywalking oap-server & ui 使用Docker安装在K8S集群以外,K8S集群中的微服务使用initContainer按命名空间将skywalking-java-agent注入到业务容器中。 SWCK有整套的解决方案,全安装在K8S群集中。 具体可参…...

微信小程序 - 手机震动
一、界面 <button type"primary" bindtap"shortVibrate">短震动</button> <button type"primary" bindtap"longVibrate">长震动</button> 二、js逻辑代码 注:文档 https://developers.weixin.qq…...
土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等
🔍 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术,可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势,还能有效评价重大生态工程…...
C# SqlSugar:依赖注入与仓储模式实践
C# SqlSugar:依赖注入与仓储模式实践 在 C# 的应用开发中,数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护,许多开发者会选择成熟的 ORM(对象关系映射)框架,SqlSugar 就是其中备受…...
HTML前端开发:JavaScript 常用事件详解
作为前端开发的核心,JavaScript 事件是用户与网页交互的基础。以下是常见事件的详细说明和用法示例: 1. onclick - 点击事件 当元素被单击时触发(左键点击) button.onclick function() {alert("按钮被点击了!&…...
【JavaSE】绘图与事件入门学习笔记
-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角,以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向,距离坐标原点x个像素;第二个是y坐标,表示当前位置为垂直方向,距离坐标原点y个像素。 坐标体系-像素 …...

selenium学习实战【Python爬虫】
selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...

推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材)
推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材) 这个项目能干嘛? 使用 gemini 2.0 的 api 和 google 其他的 api 来做衍生处理 简化和优化了文生图和图生图的行为(我的最主要) 并且有一些目标检测和切割(我用不到) 视频和 imagefx 因为没 a…...
GitHub 趋势日报 (2025年06月06日)
📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 590 cognee 551 onlook 399 project-based-learning 348 build-your-own-x 320 ne…...

逻辑回归暴力训练预测金融欺诈
简述 「使用逻辑回归暴力预测金融欺诈,并不断增加特征维度持续测试」的做法,体现了一种逐步建模与迭代验证的实验思路,在金融欺诈检测中非常有价值,本文作为一篇回顾性记录了早年间公司给某行做反欺诈预测用到的技术和思路。百度…...