vue 在图片上画框 类似于标注使用

<template>
  <div>
    <div class="parent" style="margin-top: 20px">
      <div style="width: 360px">
        <el-card class="box-card">
          <div class="text item">
            <div class="box-card-parent">
              <div v-for="item in piceList" @click="clickPice(item)">
                <el-image
                  style="width: 100px; height: 100px"
                  :src="baseUrl + '/profile/upload/' +item.picPath"></el-image>
              </div>
            </div>
          </div>
        </el-card>
      </div>
      <div style="width: 980px;">
        <el-card class="box-card" style="overflow: scroll">
          <div class="text item">
            <canvas ref="canvas" @mousedown="startDraw" @mousemove="onMouseMove" @mouseup="endDraw" :width="imageWidth"
                    :height="imageHeight"
                    style="border:1px solid #000;"></canvas>

          </div>
        </el-card>
      </div>
      <div style="width: 330px">
        <el-card class="box-card">
          <div class="text item">
            <div>
              <button v-for="(category,index) in categories" :key="index" @click="selectCategory(category)">
                {{ category.modelName }}
              </button>
              <button @click="deleteSelectedBoxes">Delete Selected Boxes</button>
              {{ imageWidth }}
              {{ imageHeight }}
            </div>
          </div>
        </el-card>
      </div>

    </div>
  </div>
</template>
<script>
import {datasetsignData, datasetsignModelId, picpath} from "@/api/model/model";

export default {
  data() {
    return {
      url: null,
      isDrawing: false,
      start: {x: 0, y: 0},
      end: {x: 0, y: 0},
      boxes: [],
      selectedCategory: '',
      categories: [],
      baseUrl: process.env.VUE_APP_BASE_API,
      image: null, // 用于存储图片
      imageWidth: null, // 图片初始宽度
      imageHeight: null, // 图片初始高度
      piceList: [],
      categoryColors: {},
    }
  },
  mounted() {
    this.loadImage(); // 组件挂载后加载图片
  },
  methods: {
    loadImage(row) {
      // 创建图像对象
      const img = new Image();
      console.log(this.$route.query.dataId)
      var dataId = {
        dataId: this.$route.query.dataId
      }
      datasetsignData(dataId).then(res => {
        this.piceList = res.data;
        var params = {
          picpath: this.piceList[0].picPath
        }
        picpath(params).then(res => {
          console.log(res, "d555")
          img.src = this.baseUrl + '/profile/upload/' + res.data.picPath, // 替换为你的图片URL
            this.imageWidth = res.data.width;
          this.imageHeight = res.data.height;
          img.onload = () => {
            this.image = img; // 图片加载成功后存储
            this.draw(); // 绘制图像
          };
          if (res.data.labels.length > 0) {
            var start = {};
            var end = {}
            for (let i = 0; i < res.data.labels.length; i++) {
              start = {x: Number(res.data.labels[i].xmin), y: Number(res.data.labels[i].ymin)}
              end = {x: Number(res.data.labels[i].xmax), y: Number(res.data.labels[i].ymax)}
              this.boxes.push({start: start, end: end, category: res.data.labels[i].name})
            }
            this.endDraw();
          }
        })
      });
      var modelId = {
        modelId: this.$route.query.modelId
      }
      datasetsignModelId(modelId).then(res => {
        this.categories = res.data;
        for (let i = 0; i < res.data.length; i++) {
          this.categoryColors = {
            [res.data[i].modelName]: res.data[i].color
          }
        }
        console.log(res, "asdasd")
      })
    },
    selectCategory(category) {
      this.selectedCategory = category;
    },
    clickPice(row) {
      this.loadImage(row);
    },
    startDraw(event) {
      this.isDrawing = true;
      const rect = this.$refs.canvas.getBoundingClientRect();
      this.start = {x: event.clientX - rect.left, y: event.clientY - rect.top};
    },
    onMouseMove(event) {
      if (!this.isDrawing) return;
      const rect = this.$refs.canvas.getBoundingClientRect();
      this.end = {x: event.clientX - rect.left, y: event.clientY - rect.top};
      this.draw();
    },
    endDraw() {
      this.isDrawing = false;
      this.boxes.push({start: this.start, end: this.end, category: this.selectedCategory.modelName});
      this.draw();
    },
    deleteSelectedBoxes() {
      this.boxes = this.boxes.filter(box => box.category !== this.selectedCategory.modelName);
      this.draw();
    },
    draw() {
      const canvas = this.$refs.canvas;
      const context = canvas.getContext('2d');
      context.clearRect(0, 0, canvas.width, canvas.height);

      // 如果图片已加载,则绘制图片
      if (this.image) {
        context.drawImage(this.image, 0, 0, this.imageWidth, this.imageHeight);
      }

      // 绘制所有的框
      this.boxes.forEach(box => {
        console.log(box,"a------")
        context.strokeStyle = this.categoryColors[box.category] || 'black'; // 默认为黑色
        context.strokeRect(box.start.x, box.start.y, box.end.x - box.start.x, box.end.y - box.start.y);
        context.fillStyle = 'white'; // 设置文字颜色为白色
        context.fillText(box.category, box.start.x, box.start.y - 5);
      });

      // 绘制当前的草图框
      if (this.isDrawing) {
        context.strokeStyle = 'blue';
        context.strokeRect(this.start.x, this.start.y, this.end.x - this.start.x, this.end.y - this.start.y);
      }
    },
  },
}
</script>

<style scoped>
canvas {
  cursor: crosshair;
}

.parent {
  width: 100%;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: 1fr;
  grid-column-gap: 0px;
  grid-row-gap: 10px;
}


.box-card {
  height: 809px;
}

.box-card-parent {
  display: grid;
  margin-right: 10px;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: 1fr;
  grid-column-gap: 10px;
  grid-row-gap: 10px;
}


.box-card-1 {
  height: 829px;
}

.box-card-2 {
  height: 829px;
}
</style>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值