本文主要是介绍如何使用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在图片上进行标注,以下代码不起作用,着实被坑到了(文末附完整代码)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!