如何使用canvas在图片上进行标注,以下代码不起作用,着实被坑到了(文末附完整代码)

本文主要是介绍如何使用canvas在图片上进行标注,以下代码不起作用,着实被坑到了(文末附完整代码),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

今天发现一个有意思的问题:

如何使用canvas在图片上进行如下的标注,以下代码不起作用,如何修改

 

原始代码如下:

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head><body><img id="myimg" src="./yidongbangong20240124103725.png"></img><canvas id="mycanvas"></canvas><script>const resData = {data: {cont: [{pos: [10, 20, 33, 40],cont: "数据标注"}]}}const img = document.getElementById("myimg");const canvas = document.getElementById("mycanvas");// 调整画布大小const ctx = canvas.getContext("2d");canvas.width = img.width;canvas.height = img.height;console.log(1);// 根据数据循环生成标注框ctx.strokeStyle = "red";// 画布上显示图片ctx.drawImage(img, 0, 0, img.width, img.height);// 计算缩小比率const widthrat = (img.naturalWidth - img.width) / img.width;const heightrat = (img.naturalHeight - img.height) / img.height;resData.data.cont.forEach(value => {// 获取标注框的x、y坐标const x = value.pos[0] * widthrat;const y = value.pos[1] * heightrat;// 获取标注框的宽、高const wid = (value.pos[2] - value.pos[0]) * widthrat;const hei = (value.pos[3] - value.pos[1]) * heightrat;// 根据获取的数据绘制描边矩形ctx.rect(x, y, wid, hei);// 绘制描边矩形上的红色填充矩形,并稍微调整样式ctx.fillStyle = "red";ctx.fillRect(x, y - 20, ctx.measureText(value.cont).width + 20, 20);// 绘制填充矩形上的白色文字,并调整坐标ctx.fillStyle = '#fff';ctx.font = "16px Arial";ctx.fillText(value.cont, x + 10, y - 4);})ctx.stroke()</script>
</body></html>

为此,特意去网上补充了一下canvas的知识,下面是canvas的画图语法:

  • drawImage(image,x,y)

 可以知道,把一张图片画到canvas上面,具体例子如下:

<img id="img" src="logo.jpg" alt="The Scream" width="325" height="200"><p>Canvas:</p>
<canvas id="myCanvas" width="250" height="300" style="border:1px solid #eee;">
您的浏览器不支持 HTML5 canvas 标签。</canvas>var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var img = document.getElementById("img");
ctx.drawImage(img, 10, 10);

 如果你也是用这个例子运行的话,也是不能运行出结果的

经过调试原始代码之后,我发现里面取到的img组件的width和height都是0

为什么都是0呢,会不会是img没有加载呢?

当然不是,因为界面都显示出来了

对于经验丰富的开发人员来说,很快就会想出原因,因为我不是专门的前端。

我实现之后才总结出原因,就是因为img是异步加载的,当我们使用canvas绘制的时候,img如果还没有加载完成,那么取到的width和height肯定都是0,因此我们需要等待图片加载完成后才能获取到宽和高。

类似解决方案代码如下:

var img = document.getElementById("img");img.onload = function() {ctx.drawImage(img, 10, 10);
}

完整代码:

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head><body><img id="myimg" src="./CSDN封面/tomcat.png" width="200" height="200" onload="draw()"></img><canvas id="mycanvas"></canvas><script>function draw() { // 图片加载下载完毕时才进行标注const resData = {data: {cont: [{pos: [10, 20, 33, 40],cont: "数据标注"}]}}const img = document.getElementById("myimg");const canvas = document.getElementById("mycanvas");// 调整画布大小const ctx = canvas.getContext("2d");canvas.width = img.width;canvas.height = img.height;console.log(1);// 根据数据循环生成标注框ctx.strokeStyle = "red";// 画布上显示图片ctx.drawImage(img, 0, 0, img.width, img.height);// 计算缩小比率const widthrat = (img.naturalWidth - img.width) / img.width;const heightrat = (img.naturalHeight - img.height) / img.height;resData.data.cont.forEach(value => {// 获取标注框的x、y坐标const x = value.pos[0] * widthrat;const y = value.pos[1] * heightrat;// 获取标注框的宽、高const wid = (value.pos[2] - value.pos[0]) * widthrat;const hei = (value.pos[3] - value.pos[1]) * heightrat;// 根据获取的数据绘制描边矩形ctx.rect(x, y, wid, hei);// 绘制描边矩形上的红色填充矩形,并稍微调整样式ctx.fillStyle = "red";ctx.fillRect(x, y - 20, ctx.measureText(value.cont).width + 20, 20);// 绘制填充矩形上的白色文字,并调整坐标ctx.fillStyle = '#fff';ctx.font = "16px Arial";ctx.fillText(value.cont, x + 10, y - 4);})ctx.stroke()}</script>
</body></html>

问题来源:

https://ask.csdn.net/questions/8102015

这篇关于如何使用canvas在图片上进行标注,以下代码不起作用,着实被坑到了(文末附完整代码)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/983835

相关文章

使用Python创建一个功能完整的Windows风格计算器程序

《使用Python创建一个功能完整的Windows风格计算器程序》:本文主要介绍如何使用Python和Tkinter创建一个功能完整的Windows风格计算器程序,包括基本运算、高级科学计算(如三... 目录python实现Windows系统计算器程序(含高级功能)1. 使用Tkinter实现基础计算器2.

SpringBoot中四种AOP实战应用场景及代码实现

《SpringBoot中四种AOP实战应用场景及代码实现》面向切面编程(AOP)是Spring框架的核心功能之一,它通过预编译和运行期动态代理实现程序功能的统一维护,在SpringBoot应用中,AO... 目录引言场景一:日志记录与性能监控业务需求实现方案使用示例扩展:MDC实现请求跟踪场景二:权限控制与

在.NET平台使用C#为PDF添加各种类型的表单域的方法

《在.NET平台使用C#为PDF添加各种类型的表单域的方法》在日常办公系统开发中,涉及PDF处理相关的开发时,生成可填写的PDF表单是一种常见需求,与静态PDF不同,带有**表单域的文档支持用户直接在... 目录引言使用 PdfTextBoxField 添加文本输入域使用 PdfComboBoxField

Git可视化管理工具(SourceTree)使用操作大全经典

《Git可视化管理工具(SourceTree)使用操作大全经典》本文详细介绍了SourceTree作为Git可视化管理工具的常用操作,包括连接远程仓库、添加SSH密钥、克隆仓库、设置默认项目目录、代码... 目录前言:连接Gitee or github,获取代码:在SourceTree中添加SSH密钥:Cl

Python中模块graphviz使用入门

《Python中模块graphviz使用入门》graphviz是一个用于创建和操作图形的Python库,本文主要介绍了Python中模块graphviz使用入门,具有一定的参考价值,感兴趣的可以了解一... 目录1.安装2. 基本用法2.1 输出图像格式2.2 图像style设置2.3 属性2.4 子图和聚

windows和Linux使用命令行计算文件的MD5值

《windows和Linux使用命令行计算文件的MD5值》在Windows和Linux系统中,您可以使用命令行(终端或命令提示符)来计算文件的MD5值,文章介绍了在Windows和Linux/macO... 目录在Windows上:在linux或MACOS上:总结在Windows上:可以使用certuti

CentOS和Ubuntu系统使用shell脚本创建用户和设置密码

《CentOS和Ubuntu系统使用shell脚本创建用户和设置密码》在Linux系统中,你可以使用useradd命令来创建新用户,使用echo和chpasswd命令来设置密码,本文写了一个shell... 在linux系统中,你可以使用useradd命令来创建新用户,使用echo和chpasswd命令来设

Python使用Matplotlib绘制3D曲面图详解

《Python使用Matplotlib绘制3D曲面图详解》:本文主要介绍Python使用Matplotlib绘制3D曲面图,在Python中,使用Matplotlib库绘制3D曲面图可以通过mpl... 目录准备工作绘制简单的 3D 曲面图绘制 3D 曲面图添加线框和透明度控制图形视角Matplotlib

Pandas中统计汇总可视化函数plot()的使用

《Pandas中统计汇总可视化函数plot()的使用》Pandas提供了许多强大的数据处理和分析功能,其中plot()函数就是其可视化功能的一个重要组成部分,本文主要介绍了Pandas中统计汇总可视化... 目录一、plot()函数简介二、plot()函数的基本用法三、plot()函数的参数详解四、使用pl

使用Python实现IP地址和端口状态检测与监控

《使用Python实现IP地址和端口状态检测与监控》在网络运维和服务器管理中,IP地址和端口的可用性监控是保障业务连续性的基础需求,本文将带你用Python从零打造一个高可用IP监控系统,感兴趣的小伙... 目录概述:为什么需要IP监控系统使用步骤说明1. 环境准备2. 系统部署3. 核心功能配置系统效果展