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