当前位置: 首页 > article >正文

vue3中怎么给图片打红框进行标注

1.需求

要求点击某个字段,根据后端返回的坐标在图上框出该字段值在图上的位置

2.效果图

3.实现代码

<template>
    <div class="annotation-container" ref="containerRef">
        <canvas ref="canvasRef"></canvas>
    </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted, watch } from 'vue';
import axios from 'axios';

const containerRef = ref(null); // 父容器引用
const canvasRef = ref(null); // 画布引用
const annotations = ref([]); // 标注数据
const props = defineProps({
    imageUrl: {
        type: String,
        required: true
    }
});

// 获取后端标注数据(或者在这里请求后端接口来获取坐标)
const fetchAnnotations = async () => {
    try {
        //  const response = await axios.get('/api/annotations');
        annotations.value = [
            {
                "left": 200,
                "top": 380,
                "width": 350,
                "height": 50
            }
        ];
    } catch (error) {
        console.error('获取标注数据失败:', error);
    }
};

// 绘制图片和红框
const drawImageAndAnnotations = () => {
    const canvas = canvasRef.value;
    const ctx = canvas.getContext('2d');
    const img = new Image();

    img.onload = () => {
        // 设置画布宽度为父容器宽度,高度按比例缩放
        const containerWidth = containerRef.value.clientWidth;
        const scale = containerWidth / img.width;
        const scaledHeight = img.height * scale;

        canvas.width = containerWidth;
        canvas.height = scaledHeight;

        // 绘制图片
        ctx.drawImage(img, 0, 0, containerWidth, scaledHeight);

        // 绘制红框
        annotations.value.forEach((annotation) => {
            const scaledLeft = annotation.left * scale;
            const scaledTop = annotation.top * scale;
            const scaledWidth = annotation.width * scale;
            const scaledHeight = annotation.height * scale;

            ctx.strokeStyle = 'red';
            ctx.lineWidth = 2;
            ctx.strokeRect(scaledLeft, scaledTop, scaledWidth, scaledHeight);
        });
    };

    img.src = props.imageUrl;
};

// 监听父容器宽度变化
const resizeObserver = new ResizeObserver(() => {
    drawImageAndAnnotations(); // 重新绘制
});

onMounted(() => {
    // 开始监听父容器大小变化
    resizeObserver.observe(containerRef.value);
    fetchAnnotations()
});


onUnmounted(() => {
    resizeObserver.disconnect(); // 停止监听
});
</script>

<style scoped>
.annotation-container {
    width: 100%;
    /* 父容器宽度自适应 */
    position: relative;
}

canvas {
    display: block;
    width: 100%;
    /* 确保画布宽度自适应 */
}
</style>

替换一下imageUrl复制可以看到效果


http://www.kler.cn/a/563401.html

相关文章:

  • Docker 搭建 MySQL 数据库
  • Spring 创建对象的流程
  • apache-maven-3.2.1
  • LeetCode热题100- 最小栈【JavaScript讲解】
  • RMII(Reduced Media Independent Interface)详解
  • Java Junit框架
  • libwebsockets交叉编译全流程
  • go-基础笔记
  • 基于SpringBoot+mybatisplus+vueJS企业数据保护系统设计与实现
  • 关于在java项目部署过程MySQL拒绝连接的分析和解决方法
  • MongoDB#常用语句
  • OpenCV开源机器视觉软件
  • 计算机毕业设计SpringBoot+Vue.js车辆管理系统(源码+文档+PPT+讲解)
  • AGI的三重架构假说:模块化认知系统设计——通向通用人工智能的工程化路径
  • 阿里重磅模型深夜开源;DeepSeek宣布开源DeepGEMM;微软开源多模态AI Agent基础模型Magma...|网易数智日报
  • HTTP与网络安全
  • 阻抗和电阻
  • 浅析 Redis 分片集群 Cluster 原理、手动搭建、动态伸缩集群、故障转移
  • 【自学笔记】Vue基础知识点总览-持续更新
  • flutter boost接入