weixin_41452476 2024-05-11 17:44 采纳率: 24%
浏览 22
已结题

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

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

img

<!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>

  • 写回答

23条回答 默认 最新

  • 笑面虎 2024-05-11 17:44
    关注

    以下内容由CHATGPT及笑面虎共同生成、有用望采纳:


    【您想要解决的问题】:您提问的目的是想要在一张图片上使用HTML5的canvas元素进行数据标注,具体来说,就是在图片上绘制矩形框并在框内添加文字说明。

    【图片内容】:您上传的图片显示了一些文字内容,包括“元气森林”和一些其他信息,但没有明确的标注框或者需要标注的对象。

    【问题出现原因】:根据您提供的代码和描述,问题可能出现在以下几个方面:

    1. 图片的加载可能还没有完成,就尝试在canvas上绘制,导致img.naturalWidthimg.naturalHeight为0。
    2. 标注框的坐标和尺寸计算可能不正确,因为widthratheightrat可能不是您想要的比例。
    3. 文字的尺寸计算可能不准确,因为ctx.measureText(value.cont).width可能没有正确计算文字的宽度。

    【问题解决方案】:为了解决这个问题,您需要确保图片完全加载后再进行绘制,并且正确计算标注框的位置和尺寸。以下是一个修改后的代码示例:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Image Annotation</title>
    </head>
    <body>
        <img id="myimg" src="./yidongbangong20240124103725.png" onload="onImageLoad(this)"></img>
        <canvas id="mycanvas"></canvas>
        <script>
            function onImageLoad(img) {
                const canvas = document.getElementById("mycanvas");
                const ctx = canvas.getContext("2d");
                // 调整画布大小
                canvas.width = img.width;
                canvas.height = img.height;
    
                const resData = {
                    data: {
                        cont: [{
                            pos: [10, 20, 33, 40],
                            cont: "数据标注"
                        }]
                    }
                }
    
                // 画布上显示图片
                ctx.drawImage(img, 0, 0, img.width, img.height);
    
                resData.data.cont.forEach(value => {
                    // 直接使用提供的坐标值,不进行比例变换
                    const x = value.pos[0];
                    const y = value.pos[1];
                    const width = value.pos[2] - value.pos[0];
                    const height = value.pos[3] - value.pos[1];
    
                    ctx.strokeStyle = "red";
                    ctx.lineWidth = 2; // 设置线宽
                    ctx.strokeRect(x, y, width, height); // 绘制矩形边框
    
                    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);
                });
            }
        </script>
    </body>
    </html>
    

    【提供代码】:上面的代码中,我添加了一个onload事件处理器,当图片加载完成后才会执行绘制逻辑。同时,我去除了可能不正确的比例变换,直接使用您提供的坐标值。

    【代码运行方式】:您需要将这段代码保存为HTML文件,并在支持HTML5的浏览器中打开。确保图片路径正确,图片能够被浏览器加载。

    【代码预期运行结果】:图片上会显示一个红色的矩形框,框内有一个白色的文字“数据标注”。

    【推荐相关链接】:

    评论 编辑记录

报告相同问题?

问题事件

  • 系统已结题 5月19日
  • 创建了问题 5月11日