web-图片标注的实现


一 :图片标注功能的实现简介

1:需要标注的图片放在底层

2:svg层正好覆盖需要标注的图片

3:由svg来画出相应的轨迹

注释: svg的坐标系:

1:以左上角为坐标系的原点(0,0)

2:X 轴的正方向向右,从 0,0 点开始向右, x 逐渐增大。Y 轴的正方向向下,从 0,0 点开始向下, y 逐 渐增大

3:坐标以像素为单位

二:标注的效果图

三: 核心代码

HTML:

 1 <div class="Labeling-canvas">
 2   <div class="image">
 3     <img src="@/assets/404.png" ref="imgLabel" id="labelValue"/><!-- 需要标注的图片 -->
 4   </div>
 5   <svg class="svglabel" ref="svglabel" @mousedown="mouseDown($event)" @mousemove="mouseMove($event)" @mouseup="onmouseup($event)" :style="{width: 100 + '%', height: 100 + '%' }">
 6     <g v-for="(rectData, index) in svgLabelShow" :key="index">
 7       <rect v-if="rectData" :x="getXPostion(rectData,27,1)" :y="rectData.ulY" :width="27" :height="26"
 8                 style="fill: #00FFFF; stroke-opacity: 1; stroke: #00FFFF; stroke-dasharray: none; stroke-width: 1;">
 9       </rect>
10           <text v-if="rectData" :x='getXPostion(rectData,18,8)' :y='parseFloat(rectData.ulY)+16'font-size='16'>
11         {{index+1}}
12       </text>
13       <rect v-if="rectData" :x="getXPostion(rectData,27,1)" :y="parseFloat(rectData.ulY)+26" :width="27" :height="24"
14                                   style="fill: #FFFFFF; stroke-opacity: 1; stroke: #00FFFF; stroke-dasharray: none; stroke-width: 1;"></rect>
15           <image v-if="rectData" @click="deleteLabel(svgLabelShow,index)" :x='getXPostion(rectData,19,7)' :y='parseFloat(rectData.ulY)+29' width='13'
16                                    height='14' xlink:href='@/assets/delete.svg'></image>
17            <rect v-if="rectData" :x="rectData.ulX" :y="rectData.ulY" :width="rectData.width" :height="rectData.height"
18                                   style="fill: none; stroke-opacity: 1; stroke: #00FFFF; stroke-dasharray: none; stroke-width: 1;"></rect>
19         </g>
20   </svg>
21 </div>
View Code

VUE: 

 1 data () {
 2     return {
 3         isclick: true,
 4         drawColor: '#00FFFF',
 5         drawElement: null, //当前移动的对象
 6         svgLabelShow: [],//显示数据,需按比例转换
 7     }
 8 },
 9 methods: {
10     //mouseDown,mouseMove,onmouseup 新建标注核心代码
11     mouseDown (e) {
12         if (!this.isclick) {//防止点击过快
13             return false;
14         } else {
15             this.clickQuick();
16         }
17         //e.button==0  没有按键或者是没有初始化
18         if (e.button == 0) {//当前为画图操作
19             const currentX = e.offsetX;//offsetX,offsetY相对于带有定位的父盒子的x,y坐标
20             const currentY = e.offsetY;
21             this.drawElement = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
22             this.drawElement.setAttribute('x', currentX);
23             this.drawElement.setAttribute('y', currentY);
24             this.drawElement.setAttribute('width', 0);
25             this.drawElement.setAttribute('height', 0);
26             this.drawElement.dataset.dataType = 'markRect';
27             this.$refs.svglabel.appendChild(this.drawElement);
28             this.drawElementStyle(this.drawElement);
29         }
30     },
31     mouseMove (e) {
32         if (this.drawElement == null || this.corpusActionType != 'label') {
33             return false;
34         }
35         if (e.button == 0) {//当前为画图操作
36             const currentX = e.offsetX;
37             const currentY = e.offsetY;
38             const startX = this.drawElement.getAttribute('x');
39             const startY = this.drawElement.getAttribute('y');
40             const rectX =startX;
41             const rectY =startY;
42             const rectWith = Math.abs(currentX - startX);
43             const rectHeight = Math.abs(currentY - startY);
44             this.drawElement.setAttribute('x', rectX);
45             this.drawElement.setAttribute('y', rectY);
46             this.drawElement.setAttribute('width', rectWith);
47             this.drawElement.setAttribute('height', rectHeight);
48         }
49     },
50     onmouseup (e) {
51         if (this.drawElement == null) {
52             return;
53         }
54         if (e.button == 0) {
55             const rectX = this.drawElement.getAttribute('x');
56             const rectY = this.drawElement.getAttribute('y');
57             const rectWidth = this.drawElement.getAttribute('width');
58             const rectHeight = this.drawElement.getAttribute('height');
59             if (rectWidth == 0 || rectHeight == 0 || !rectX || !rectY) {//不符合条件的矩形取消
60                 this.drawElement.parentNode.removeChild(this.drawElement);
61                 this.drawElement = null;
62             } else {
63                 this.svgLabelShow.push({ulX: rectX, ulY: rectY, width: rectWidth, height: rectHeight, labelName: 'table'});
64                 console.log('this.svgLabelShow', this.svgLabelShow);
65                 this.drawElementStyle(e.target);
66                 this.drawElement.parentNode.removeChild(this.drawElement);
67                 this.drawElement = null;
68             }
69         }
70     },
71     //设置标注框的样式  0:正常状态  1: 高亮状态   2: 可编辑状态
72     drawElementStyle (drawElement) {
73         drawElement.style.fill = 'none';
74         drawElement.style.strokeOpacity = 1;
75         drawElement.style.stroke = this.drawColor;
76         drawElement.style.strokeDasharray = 'none';
77         drawElement.style.strokeWidth = 1;
78     },
79     clickQuick () {
80         if (this.isclick) {
81             this.isclick = false;
82             setTimeout(() => {
83                 this.isclick = true;
84             }, 500);
85         }
86     },
87     getXPostion (labelData, xPostion, left) {
88         if (parseFloat(labelData.ulX) < 27) {
89             return parseFloat(labelData.ulX) + parseFloat(labelData.width) + left;
90         } else {
91             return parseFloat(labelData.ulX) - xPostion;
92         }
93     },
94 }
View Code

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM