Skip to content

KLImageAnnotation

考拉图像标注组件

效果

vue
<script setup lang="ts">
import { ref } from 'vue';
import { ElMessage } from 'element-plus';
import { useDrawRect } from '../composables/drawRect';
import type { annotation } from '../components/KLImageAnnotation.ts'

const imgSrc = 'img/test.png';
const imgMaskSrc = '';
const width = 5120;
const height = 5120;
const annotations = ref<annotation[]>([
  { title: '类型', content: '图像标注' },
  { title: '时间', content: new Date().toLocaleString() },
])
const rects = ref([
  { id: 1, name: '窗前明月光', position: [400, 3000, 300, 300] },
  { id: 2, name: '疑是地上霜', position: [500, 2800, 420, 320] },
  { id: 3, name: '举头望明月', position: [500, 3000, 380, 500] },
  { id: 4, name: '低头思故乡', position: [1200, 3000, 520, 500] },
])

const imageAnnotation = ref();
const { mousedown, rectPath } = useDrawRect({
  getPositionFn(e: MouseEvent) {
    return imageAnnotation.value.getPosition(e);
  },
  rectCallback: () => true,
  button: 2,
  enable: true,
})

function contextmenu(e: MouseEvent) {
  e.preventDefault();
  ElMessage.success('右键');
}

function submitEvent() {
  
}
</script>
<template>
  <div class="shadow-block p20" style="height: 600px">
    <KLImageAnnotation ref="imageAnnotation" :imgSrc="imgSrc" :imgMaskSrc="imgMaskSrc" :width="width" :height="height"
      :annotations="annotations" :rects="rects" :mousedownImageEvent="mousedown" :contextmenuImageEvent="contextmenu" :submitEvent="submitEvent">
      <template #image>
        <svg :width="width" :height="height" xmlns="http://www.w3.org/2000/svg">
          <g stroke="#ff0000" stroke-opacity="1" :stroke-width="4" fill="none">
            <path :d="rectPath" />
          </g>
        </svg>
      </template>
      <template #rects-detail="{ curSelectIndex, selectByIndex }">
        <div class="list-table">
          <div class="list-row list-header flex-center">
            <div class="row-id">编号</div>
            <div class="row-name">详情</div>
          </div>
          <el-scrollbar height="calc(100% - 34px)">
            <div class="list-row flex-center" :class="{ current: curSelectIndex === index }"
              v-for="(rect, index) in rects" @click="selectByIndex(index)" :key="index">
              <div class="row-id">{{ index + 1 }}</div>
              <div class="row-name">{{ rect.name }}</div>
            </div>
          </el-scrollbar>
        </div>
      </template>
    </KLImageAnnotation>
  </div>
</template>

类型定义

ts
/** 文字标注信息项 */
export interface annotation {
  title: string;
  content: string
}

/** 图像标注区域 */
export interface rect {
  id: number;
  /** [x, y, width, height] */
  position: number[];
  color?: string;
  measureDesc?: string;
}

/** 选中标注项触发源 */
export enum RectChangeEventFrom {
  /** 图像区域 */
  IMAGE = 'IMAGE',
  /** 键盘 */
  KEYBOARD = 'KEYBOARD',
  /** 列表 */
  TABLE = 'TABLE',
}

/** 当前被选中的标注项及其触发源 */
export interface RectChangeEvent {
  /** 触发源;接受事件端可根据此字段决定要不要做出反馈,如标注列表滚动到当前标注项 */
  from: string | null,
  /** 当前被选中的标注项 */
  rect: rect | null,
  /** 是否静默触发;silent为true时各接受事件端禁止响应rect变化 */
  silent: boolean,
}

属性

ts
export interface ImageAnnotationProps {
  /** 图像地址 */
  imgSrc: string;
  /** 图像对应掩膜地址 */
  imgMaskSrc: string;
  /** 图像宽 */
  width: number;
  /** 图像高 */
  height: number;
  /** 标注信息列表 */
  annotations: annotation[];
  /** 标注框列表 */
  rects: rect[];
  /** 图像标注框列表,默认使用rects */
  imgRects?: rect[];
  /** 鼠标事件 */
  mousedownImageEvent?: (e: MouseEvent) => void;
  /** 鼠标右键事件 */
  contextmenuImageEvent?: (e: MouseEvent) => void;
  /** 点击确认按钮事件 */
  submitEvent: () => void;
}

slot

插槽名说明数据
image图像区域{scale: number}
canvas画布区域-
text-detail文字解说区域-
image-detail图像地址详细说明区域-
rects-detail标注矩形框列表详情区域RectsListProps
submit确认按钮区域-
typescript
// 标注矩形框列表详情区域传递参数
type RectsListProps = {
  // 查看方法selectByRect
  selectByRect: (param: RectChangeEvent) => void,
  // 查看方法selectByIndex
  selectByIndex: (index: number, from: string, silent?: boolean) => void,
  // 当前被选中的标注项对应索引
  curSelectIndex: number,
  // 当前被选中的标注项及其触发源
  curRectChange: RectChangeEvent,
}

方法

getPosition 获取鼠标相对图像的坐标

typescript
getPosition(e: MouseEvent): coor | null

scrollToRect 图像视野移动到指定区域

typescript
// position [x,y,width,height]
scrollToRect(position: number[]): void

selectByRect 选择指定标注

typescript
selectByRect(param: RectChangeEvent): void

selectByRect 选择指定标注

typescript
selectByIndex(index: number, from: string, silent?: boolean): void

reset 重置画布区域

typescript
reset(): void