|
|
@@ -1,14 +1,13 @@
|
|
|
<template>
|
|
|
<div class="canvas-container" ref="canvasContainer">
|
|
|
- <div
|
|
|
- class="canvas float-left"
|
|
|
- ref="yfcontainer"
|
|
|
- v-loading="loading"
|
|
|
- >
|
|
|
+ <div class="canvas float-left" ref="yfcontainer" v-loading="loading">
|
|
|
<!-- 画布 -->
|
|
|
<canvas
|
|
|
- :style="{width: canvasSize.width + 'px', height: canvasSize.height + 'px'}"
|
|
|
- canvas-id="yfCanvas"
|
|
|
+ :style="{
|
|
|
+ width: canvasSize.width + 'px',
|
|
|
+ height: canvasSize.height + 'px',
|
|
|
+ }"
|
|
|
+ canvas-id="yfCanvas"
|
|
|
id="yfCanvas"
|
|
|
></canvas>
|
|
|
<!-- 文本标签 -->
|
|
|
@@ -24,82 +23,81 @@
|
|
|
</span>
|
|
|
</div> -->
|
|
|
</div>
|
|
|
-
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
-import Panel from './comps/panel.vue'
|
|
|
-import Tools from './comps/tools.vue'
|
|
|
-import Annotation from './comps/Annotation.vue'
|
|
|
-let myRatio = 1
|
|
|
+import Panel from './comps/panel.vue';
|
|
|
+import Tools from './comps/tools.vue';
|
|
|
+import Annotation from './comps/Annotation.vue';
|
|
|
+let myRatio = 1;
|
|
|
export default {
|
|
|
props: {
|
|
|
markItem: {
|
|
|
type: Object,
|
|
|
default: () => ({
|
|
|
addr: 'https://bigdata-image.oss-cn-hangzhou.aliyuncs.com/Basics/cbd/666000000000001/2025/7/11/001.jpg',
|
|
|
- mark:[],
|
|
|
- is_mark:0,
|
|
|
- label: "[{'71': [480, 47, 520, 91, 1.0]}, {'71': [513, 102, 545, 155, 1.0]}, {'71': [690, 238, 740, 272, 1.0]}, {'71': [298, 471, 335, 514, 1.0]}, {'71': [250, 379, 300, 407, 1.0]}, {'71': [106, 40, 143, 89, 1.0]}, {'71': [46, 12, 124, 58, 0.99]}, {'71': [2, 90, 41, 133, 0.98]}, {'71': [767, 189, 799, 237, 0.98]}, {'71': [721, 175, 758, 216, 0.92]}, {'71': [685, 132, 727, 166, 0.35]}]",
|
|
|
- })
|
|
|
+ mark: [],
|
|
|
+ is_mark: 0,
|
|
|
+ label:
|
|
|
+ "[{'71': [480, 47, 520, 91, 1.0]}, {'71': [513, 102, 545, 155, 1.0]}, {'71': [690, 238, 740, 272, 1.0]}, {'71': [298, 471, 335, 514, 1.0]}, {'71': [250, 379, 300, 407, 1.0]}, {'71': [106, 40, 143, 89, 1.0]}, {'71': [46, 12, 124, 58, 0.99]}, {'71': [2, 90, 41, 133, 0.98]}, {'71': [767, 189, 799, 237, 0.98]}, {'71': [721, 175, 758, 216, 0.92]}, {'71': [685, 132, 727, 166, 0.35]}]",
|
|
|
+ }),
|
|
|
},
|
|
|
isInitFullScreen: {
|
|
|
type: Boolean,
|
|
|
- default: false
|
|
|
+ default: false,
|
|
|
},
|
|
|
reIdentify: {
|
|
|
type: Boolean,
|
|
|
- default: true
|
|
|
+ default: true,
|
|
|
},
|
|
|
title: {
|
|
|
type: String,
|
|
|
- default: '目录'
|
|
|
+ default: '目录',
|
|
|
},
|
|
|
|
|
|
typeName: {
|
|
|
type: Number,
|
|
|
- default: 1 // 1: 测报灯 2:病虫害可视监测 3:吸虫塔 4:孢子仪
|
|
|
- }
|
|
|
+ default: 1, // 1: 测报灯 2:病虫害可视监测 3:吸虫塔 4:孢子仪
|
|
|
+ },
|
|
|
},
|
|
|
watch: {
|
|
|
markItem: {
|
|
|
handler(newVal) {
|
|
|
- console.log('markItem变化:', newVal, this.ctx)
|
|
|
+ console.log('markItem变化:', newVal, this.ctx);
|
|
|
// 当markItem变化时,重新加载图片和标注
|
|
|
if (!newVal.addr && this.ctx) {
|
|
|
- this.clearCanvas()
|
|
|
- return
|
|
|
+ this.clearCanvas();
|
|
|
+ return;
|
|
|
}
|
|
|
if (this.ctx) {
|
|
|
- this.loadImage()
|
|
|
+ this.loadImage();
|
|
|
}
|
|
|
},
|
|
|
- deep: true
|
|
|
- }
|
|
|
+ deep: true,
|
|
|
+ },
|
|
|
},
|
|
|
components: {
|
|
|
Panel,
|
|
|
Tools,
|
|
|
- Annotation
|
|
|
+ Annotation,
|
|
|
},
|
|
|
name: 'Draw',
|
|
|
computed: {
|
|
|
inputStyle() {
|
|
|
return {
|
|
|
left: `${this.inputPosition.x}px`,
|
|
|
- top: `${this.inputPosition.y}px`
|
|
|
- }
|
|
|
+ top: `${this.inputPosition.y}px`,
|
|
|
+ };
|
|
|
},
|
|
|
canvasStyle() {
|
|
|
return {
|
|
|
- cursor: this.mode === 'draw' ? 'crosshair' : 'grab'
|
|
|
- }
|
|
|
+ cursor: this.mode === 'draw' ? 'crosshair' : 'grab',
|
|
|
+ };
|
|
|
},
|
|
|
fullScreenHtml() {
|
|
|
- return this.$refs.canvasContainer
|
|
|
- }
|
|
|
-
|
|
|
+ return this.$refs.canvasContainer;
|
|
|
+ },
|
|
|
},
|
|
|
data() {
|
|
|
return {
|
|
|
@@ -115,7 +113,7 @@ export default {
|
|
|
modeLabels: {
|
|
|
draw: 'D绘制',
|
|
|
drag: 'S拖拽',
|
|
|
- select: '空格选择'
|
|
|
+ select: '空格选择',
|
|
|
},
|
|
|
isDragging: false,
|
|
|
isDrawing: false,
|
|
|
@@ -147,299 +145,301 @@ export default {
|
|
|
colorIndex: 0,
|
|
|
originDataLength: 0, // 用于记录原始数据长度
|
|
|
pestLibrary: {},
|
|
|
- canvasSize:{width:310,height:279}
|
|
|
- }
|
|
|
+ canvasSize: { width: 310, height: 279 },
|
|
|
+ };
|
|
|
},
|
|
|
created() {
|
|
|
- this.getAllPestList()
|
|
|
+ this.getAllPestList();
|
|
|
},
|
|
|
mounted() {
|
|
|
// console.log('初始化markItem:', this.markItem)
|
|
|
-
|
|
|
- uni.getSystemInfo({
|
|
|
- success: (res) => {
|
|
|
- this.canvasSize.width = res.windowWidth-(24*2+16*2)
|
|
|
- }
|
|
|
- })
|
|
|
- this.$nextTick(()=>{
|
|
|
-
|
|
|
- })
|
|
|
- },
|
|
|
- beforeDestroy() {
|
|
|
-
|
|
|
+
|
|
|
+ uni.getSystemInfo({
|
|
|
+ success: (res) => {
|
|
|
+ this.canvasSize.width = res.windowWidth - (24 * 2 + 16 * 2);
|
|
|
+ },
|
|
|
+ });
|
|
|
+ this.$nextTick(() => {});
|
|
|
},
|
|
|
+ beforeDestroy() {},
|
|
|
methods: {
|
|
|
-
|
|
|
// 切换上一个下一个
|
|
|
changeItem(type) {
|
|
|
-
|
|
|
- this.$emit('changeItem', { type: type, isFullScreen: this.isFullScreen })
|
|
|
+ this.$emit('changeItem', { type: type, isFullScreen: this.isFullScreen });
|
|
|
},
|
|
|
changeMode(modeType) {
|
|
|
- this.mode = modeType
|
|
|
+ this.mode = modeType;
|
|
|
},
|
|
|
|
|
|
resetPest() {
|
|
|
// 通知业务上层处理逻辑
|
|
|
- this.exitFullScreen()
|
|
|
- this.$emit('resetPest')
|
|
|
+ this.exitFullScreen();
|
|
|
+ this.$emit('resetPest');
|
|
|
},
|
|
|
// 查看原图
|
|
|
checkImagePreview() {
|
|
|
- this.$refs.imgPreview.click()
|
|
|
+ this.$refs.imgPreview.click();
|
|
|
},
|
|
|
|
|
|
linkStyle(tag) {
|
|
|
- let x = Math.min(tag.startX, tag.endX)
|
|
|
- let y = Math.min(tag.startY, tag.endY)
|
|
|
+ let x = Math.min(tag.startX, tag.endX);
|
|
|
+ let y = Math.min(tag.startY, tag.endY);
|
|
|
|
|
|
- const top = y * this.scale + this.offsetY - 20 + 'px'
|
|
|
- const left = x * this.scale + this.offsetX + 'px'
|
|
|
+ const top = y * this.scale + this.offsetY - 20 + 'px';
|
|
|
+ const left = x * this.scale + this.offsetX + 'px';
|
|
|
return {
|
|
|
top,
|
|
|
left,
|
|
|
color: tag.color,
|
|
|
- 'pointer-events': this.isMoving ? 'none' : 'auto'
|
|
|
- }
|
|
|
+ 'pointer-events': this.isMoving ? 'none' : 'auto',
|
|
|
+ };
|
|
|
},
|
|
|
initCanvas() {
|
|
|
-
|
|
|
- this.ctx = uni.createCanvasContext('yfCanvas', this)
|
|
|
- console.log(this.ctx)
|
|
|
- this.loadImage()
|
|
|
-
|
|
|
+ this.ctx = uni.createCanvasContext('yfCanvas', this);
|
|
|
+ console.log(this.ctx);
|
|
|
+ this.loadImage();
|
|
|
},
|
|
|
|
|
|
loadImage() {
|
|
|
if (!this.markItem.addr) {
|
|
|
- this.loading = false
|
|
|
- return
|
|
|
+ this.loading = false;
|
|
|
+ return;
|
|
|
}
|
|
|
|
|
|
- uni.getImageInfo({
|
|
|
- src: this.markItem.addr,
|
|
|
- success: (res) => {
|
|
|
- this.imageLoaded = true
|
|
|
- this.backgroundImage = res
|
|
|
- this.originalImageSize = {
|
|
|
- width: this.backgroundImage.width,
|
|
|
- height: this.backgroundImage.height
|
|
|
- }
|
|
|
- this.rectangles = [] // 清除之前的标注
|
|
|
- this.selectedRect = null
|
|
|
- this.adjustImagePosition()
|
|
|
- this.initMarkData()
|
|
|
- this.draw()
|
|
|
- this.loading = false
|
|
|
- },
|
|
|
- fail: (err) => {
|
|
|
- this.loading = false
|
|
|
- this.$message.error('图片加载失败')
|
|
|
- }
|
|
|
- })
|
|
|
-
|
|
|
+ uni.getImageInfo({
|
|
|
+ src: this.markItem.addr,
|
|
|
+ success: (res) => {
|
|
|
+ this.imageLoaded = true;
|
|
|
+ this.backgroundImage = res;
|
|
|
+ this.originalImageSize = {
|
|
|
+ width: this.backgroundImage.width,
|
|
|
+ height: this.backgroundImage.height,
|
|
|
+ };
|
|
|
+ this.rectangles = []; // 清除之前的标注
|
|
|
+ this.selectedRect = null;
|
|
|
+ this.adjustImagePosition();
|
|
|
+ this.initMarkData();
|
|
|
+ this.draw();
|
|
|
+ this.loading = false;
|
|
|
+ },
|
|
|
+ fail: (err) => {
|
|
|
+ this.loading = false;
|
|
|
+ this.$message.error('图片加载失败');
|
|
|
+ },
|
|
|
+ });
|
|
|
},
|
|
|
|
|
|
adjustImagePosition() {
|
|
|
- if (!this.imageLoaded) return
|
|
|
+ if (!this.imageLoaded) return;
|
|
|
|
|
|
- const canvas = this.canvasSize
|
|
|
- const canvasAspect = canvas.width / canvas.height
|
|
|
- const imageAspect = this.originalImageSize.width / this.originalImageSize.height
|
|
|
+ const canvas = this.canvasSize;
|
|
|
+ const canvasAspect = canvas.width / canvas.height;
|
|
|
+ const imageAspect =
|
|
|
+ this.originalImageSize.width / this.originalImageSize.height;
|
|
|
|
|
|
// 计算等比缩放的尺寸
|
|
|
if (imageAspect > canvasAspect) {
|
|
|
- this.imageScale = canvas.width / this.originalImageSize.width
|
|
|
+ this.imageScale = canvas.width / this.originalImageSize.width;
|
|
|
} else {
|
|
|
- this.imageScale = canvas.height / this.originalImageSize.height
|
|
|
+ this.imageScale = canvas.height / this.originalImageSize.height;
|
|
|
}
|
|
|
// this.imageScale = 0.8
|
|
|
// 根据图片的宽度来定义缩放比例
|
|
|
if (this.originalImageSize.width >= 5000) {
|
|
|
- this.baseScale = 0.25
|
|
|
+ this.baseScale = 0.25;
|
|
|
} else if (this.originalImageSize.width >= 4000) {
|
|
|
- this.baseScale = 0.31
|
|
|
+ this.baseScale = 0.31;
|
|
|
} else if (this.originalImageSize.width < 4000) {
|
|
|
- this.baseScale = 0.4
|
|
|
+ this.baseScale = 0.4;
|
|
|
}
|
|
|
// 用来处理图片等比例显示
|
|
|
- this.markScale = 1 - (this.baseScale - this.imageScale) / this.baseScale
|
|
|
+ this.markScale = 1 - (this.baseScale - this.imageScale) / this.baseScale;
|
|
|
// 窗口大小改变的时候使用
|
|
|
- myRatio = this.imageScale / this.lastImageScale
|
|
|
+ myRatio = this.imageScale / this.lastImageScale;
|
|
|
|
|
|
- this.lastImageScale = this.imageScale
|
|
|
+ this.lastImageScale = this.imageScale;
|
|
|
// 计算图片显示区域
|
|
|
this.imageRect = {
|
|
|
x: 0,
|
|
|
y: 0,
|
|
|
width: this.originalImageSize.width * this.imageScale,
|
|
|
- height: this.originalImageSize.height * this.imageScale
|
|
|
- }
|
|
|
+ height: this.originalImageSize.height * this.imageScale,
|
|
|
+ };
|
|
|
|
|
|
// 初始位置居中
|
|
|
- this.scale = 1
|
|
|
- this.offsetX = (canvas.width - this.imageRect.width) / 2
|
|
|
- this.offsetY = (canvas.height - this.imageRect.height) / 2
|
|
|
+ this.scale = 1;
|
|
|
+ this.offsetX = (canvas.width - this.imageRect.width) / 2;
|
|
|
+ this.offsetY = (canvas.height - this.imageRect.height) / 2;
|
|
|
},
|
|
|
|
|
|
isPointInImage(x, y) {
|
|
|
- return x >= 0 && x <= this.imageRect.width && y >= 0 && y <= this.imageRect.height
|
|
|
+ return (
|
|
|
+ x >= 0 &&
|
|
|
+ x <= this.imageRect.width &&
|
|
|
+ y >= 0 &&
|
|
|
+ y <= this.imageRect.height
|
|
|
+ );
|
|
|
},
|
|
|
constrainRect(rect) {
|
|
|
// 确保矩形完全在图片区域内
|
|
|
- const startX = Math.max(0, Math.min(this.imageRect.width, rect.startX))
|
|
|
- const startY = Math.max(0, Math.min(this.imageRect.height, rect.startY))
|
|
|
- const endX = Math.max(0, Math.min(this.imageRect.width, rect.endX))
|
|
|
- const endY = Math.max(0, Math.min(this.imageRect.height, rect.endY))
|
|
|
+ const startX = Math.max(0, Math.min(this.imageRect.width, rect.startX));
|
|
|
+ const startY = Math.max(0, Math.min(this.imageRect.height, rect.startY));
|
|
|
+ const endX = Math.max(0, Math.min(this.imageRect.width, rect.endX));
|
|
|
+ const endY = Math.max(0, Math.min(this.imageRect.height, rect.endY));
|
|
|
|
|
|
return {
|
|
|
...rect,
|
|
|
startX,
|
|
|
startY,
|
|
|
endX,
|
|
|
- endY
|
|
|
- }
|
|
|
+ endY,
|
|
|
+ };
|
|
|
},
|
|
|
|
|
|
-
|
|
|
handleLabelChange() {
|
|
|
- this.draw()
|
|
|
+ this.draw();
|
|
|
},
|
|
|
|
|
|
getRectAt(x, y) {
|
|
|
// 从后往前检查,这样最后绘制的矩形会优先被选中
|
|
|
for (let i = this.rectangles.length - 1; i >= 0; i--) {
|
|
|
- const rect = this.rectangles[i]
|
|
|
- const left = Math.min(rect.startX, rect.endX)
|
|
|
- const right = Math.max(rect.startX, rect.endX)
|
|
|
- const top = Math.min(rect.startY, rect.endY)
|
|
|
- const bottom = Math.max(rect.startY, rect.endY)
|
|
|
+ const rect = this.rectangles[i];
|
|
|
+ const left = Math.min(rect.startX, rect.endX);
|
|
|
+ const right = Math.max(rect.startX, rect.endX);
|
|
|
+ const top = Math.min(rect.startY, rect.endY);
|
|
|
+ const bottom = Math.max(rect.startY, rect.endY);
|
|
|
|
|
|
if (x >= left && x <= right && y >= top && y <= bottom) {
|
|
|
- return rect
|
|
|
+ return rect;
|
|
|
}
|
|
|
}
|
|
|
- return null
|
|
|
+ return null;
|
|
|
},
|
|
|
|
|
|
deleteSelected() {
|
|
|
if (this.selectedRect) {
|
|
|
- this.deleteRect(this.selectedRect.id)
|
|
|
- this.selectedRect = null
|
|
|
+ this.deleteRect(this.selectedRect.id);
|
|
|
+ this.selectedRect = null;
|
|
|
}
|
|
|
},
|
|
|
|
|
|
deleteRect(id) {
|
|
|
- this.rectangles = this.rectangles.filter(rect => rect.id !== id)
|
|
|
+ this.rectangles = this.rectangles.filter((rect) => rect.id !== id);
|
|
|
if (this.selectedRect && this.selectedRect.id === id) {
|
|
|
- this.selectedRect = null
|
|
|
+ this.selectedRect = null;
|
|
|
}
|
|
|
- this.showInput = false
|
|
|
- this.currentRectId = null
|
|
|
- this.draw()
|
|
|
+ this.showInput = false;
|
|
|
+ this.currentRectId = null;
|
|
|
+ this.draw();
|
|
|
},
|
|
|
deleteSpan(e, id) {
|
|
|
- e.preventDefault()
|
|
|
- e.stopPropagation()
|
|
|
- this.isDrawing = false
|
|
|
- this.deleteRect(id)
|
|
|
+ e.preventDefault();
|
|
|
+ e.stopPropagation();
|
|
|
+ this.isDrawing = false;
|
|
|
+ this.deleteRect(id);
|
|
|
},
|
|
|
clearCanvas() {
|
|
|
- this.loading = false
|
|
|
- this.imageLoaded = false
|
|
|
- this.rectangles = []
|
|
|
- this.selectedRect = null
|
|
|
- this.showInput = false
|
|
|
- this.currentRectId = null
|
|
|
- const canvas = this.canvasSize
|
|
|
- const ctx = this.ctx
|
|
|
+ this.loading = false;
|
|
|
+ this.imageLoaded = false;
|
|
|
+ this.rectangles = [];
|
|
|
+ this.selectedRect = null;
|
|
|
+ this.showInput = false;
|
|
|
+ this.currentRectId = null;
|
|
|
+ const canvas = this.canvasSize;
|
|
|
+ const ctx = this.ctx;
|
|
|
|
|
|
// 清除画布
|
|
|
- ctx.clearRect(0, 0, canvas.width, canvas.height)
|
|
|
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
|
},
|
|
|
// 修改后的 draw 方法
|
|
|
draw() {
|
|
|
- const canvas = this.canvasSize
|
|
|
- const ctx = this.ctx
|
|
|
+ const canvas = this.canvasSize;
|
|
|
+ const ctx = this.ctx;
|
|
|
|
|
|
// 清除画布
|
|
|
- ctx.clearRect(0, 0, canvas.width, canvas.height)
|
|
|
- console.log(this.offsetX, this.offsetY)
|
|
|
- // 保存当前状态
|
|
|
- ctx.save()
|
|
|
-
|
|
|
- // 应用变换(缩放和平移)
|
|
|
- ctx.translate(this.offsetX, this.offsetY)
|
|
|
- ctx.scale(this.scale, this.scale)
|
|
|
-
|
|
|
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
|
+ console.log(this.offsetX, this.offsetY);
|
|
|
+ // 保存当前状态
|
|
|
+ ctx.save();
|
|
|
+
|
|
|
+ // 应用变换(缩放和平移)
|
|
|
+ ctx.translate(this.offsetX, this.offsetY);
|
|
|
+ ctx.scale(this.scale, this.scale);
|
|
|
+
|
|
|
// 绘制背景图片(不再除以this.scale)
|
|
|
if (this.imageLoaded && this.backgroundImage) {
|
|
|
- const displayWidth = this.originalImageSize.width * this.imageScale
|
|
|
- const displayHeight = this.originalImageSize.height * this.imageScale
|
|
|
+ const displayWidth = this.originalImageSize.width * this.imageScale;
|
|
|
+ const displayHeight = this.originalImageSize.height * this.imageScale;
|
|
|
// ctx.imageSmoothingEnabled = true
|
|
|
// ctx.imageSmoothingQuality = 'high'
|
|
|
- ctx.drawImage(this.backgroundImage.path, 0, 0, displayWidth, displayHeight)
|
|
|
-
|
|
|
- }
|
|
|
- console.log('绘制::',this.rectangles)
|
|
|
+ ctx.drawImage(
|
|
|
+ this.backgroundImage.path,
|
|
|
+ 0,
|
|
|
+ 0,
|
|
|
+ displayWidth,
|
|
|
+ displayHeight
|
|
|
+ );
|
|
|
+ }
|
|
|
+ console.log('绘制::', this.rectangles);
|
|
|
// 绘制所有已保存的矩形(添加约束)
|
|
|
- this.rectangles.forEach(rect => {
|
|
|
- const constrainedRect = this.constrainRect(rect)
|
|
|
- this.drawRectangle(constrainedRect, rect === this.selectedRect)
|
|
|
- })
|
|
|
+ this.rectangles.forEach((rect) => {
|
|
|
+ const constrainedRect = this.constrainRect(rect);
|
|
|
+ this.drawRectangle(constrainedRect, rect === this.selectedRect);
|
|
|
+ });
|
|
|
|
|
|
// 绘制当前正在绘制的矩形(添加约束)
|
|
|
if (this.currentRect) {
|
|
|
- const constrainedRect = this.constrainRect(this.currentRect)
|
|
|
- this.drawRectangle(constrainedRect, false)
|
|
|
+ const constrainedRect = this.constrainRect(this.currentRect);
|
|
|
+ this.drawRectangle(constrainedRect, false);
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
// 恢复状态
|
|
|
- ctx.restore()
|
|
|
- ctx.draw()
|
|
|
+ ctx.restore();
|
|
|
+ ctx.draw();
|
|
|
},
|
|
|
|
|
|
drawRectangle(rect, isSelected) {
|
|
|
- const ctx = this.ctx
|
|
|
+ const ctx = this.ctx;
|
|
|
|
|
|
- const x = Math.min(rect.startX, rect.endX)
|
|
|
- const y = Math.min(rect.startY, rect.endY)
|
|
|
- const width = Math.abs(rect.endX - rect.startX)
|
|
|
- const height = Math.abs(rect.endY - rect.startY)
|
|
|
+ const x = Math.min(rect.startX, rect.endX);
|
|
|
+ const y = Math.min(rect.startY, rect.endY);
|
|
|
+ const width = Math.abs(rect.endX - rect.startX);
|
|
|
+ const height = Math.abs(rect.endY - rect.startY);
|
|
|
|
|
|
// 绘制矩形填充
|
|
|
|
|
|
- ctx.strokeStyle = rect.color
|
|
|
- ctx.lineWidth = 2 / this.scale
|
|
|
- ctx.strokeRect(x, y, width, height)
|
|
|
+ ctx.strokeStyle = rect.color;
|
|
|
+ ctx.lineWidth = 2 / this.scale;
|
|
|
+ ctx.strokeRect(x, y, width, height);
|
|
|
// 绘制标签文本
|
|
|
if (rect.text) {
|
|
|
- ctx.fillStyle = rect.color
|
|
|
- ctx.font = `${14 / this.scale}px Arial`
|
|
|
- ctx.fillText(rect.text, x + 12 / this.scale, y - 6 / this.scale)
|
|
|
+ ctx.fillStyle = rect.color;
|
|
|
+ ctx.font = `${14 / this.scale}px Arial`;
|
|
|
+ ctx.fillText(rect.text, x + 12 / this.scale, y - 6 / this.scale);
|
|
|
}
|
|
|
-
|
|
|
-
|
|
|
},
|
|
|
|
|
|
// 获取数据
|
|
|
getData() {
|
|
|
- const data = this.rectangles.map(rect => {
|
|
|
+ const data = this.rectangles.map((rect) => {
|
|
|
return {
|
|
|
startX: parseFloat((rect.startX / this.markScale).toFixed(2)),
|
|
|
startY: parseFloat((rect.startY / this.markScale).toFixed(2)),
|
|
|
- width: parseFloat((Math.abs(rect.startX - rect.endX) / this.markScale).toFixed(2)),
|
|
|
- height: parseFloat((Math.abs(rect.startY - rect.endY) / this.markScale).toFixed(2)),
|
|
|
- text: rect.text
|
|
|
- }
|
|
|
- })
|
|
|
- this.originDataLength = data.length
|
|
|
- return data
|
|
|
+ width: parseFloat(
|
|
|
+ (Math.abs(rect.startX - rect.endX) / this.markScale).toFixed(2)
|
|
|
+ ),
|
|
|
+ height: parseFloat(
|
|
|
+ (Math.abs(rect.startY - rect.endY) / this.markScale).toFixed(2)
|
|
|
+ ),
|
|
|
+ text: rect.text,
|
|
|
+ };
|
|
|
+ });
|
|
|
+ this.originDataLength = data.length;
|
|
|
+ return data;
|
|
|
// return JSON.stringify(data)
|
|
|
},
|
|
|
// 处理渲染数据
|
|
|
async initMarkData() {
|
|
|
-
|
|
|
const colorList = [
|
|
|
'#FF0000',
|
|
|
'#00FFC2',
|
|
|
@@ -456,25 +456,26 @@ export default {
|
|
|
'#007880',
|
|
|
'#00C2FF',
|
|
|
'#C74C4C',
|
|
|
- '#EB00FF'
|
|
|
- ]
|
|
|
+ '#EB00FF',
|
|
|
+ ];
|
|
|
if (this.markItem.is_mark === 0) {
|
|
|
// 机器标注,取label
|
|
|
- let aiLabel = []
|
|
|
+ let aiLabel = [];
|
|
|
if (this.markItem.label) {
|
|
|
- aiLabel = JSON.parse(this.markItem.label.replace(/'/g, '"'))
|
|
|
+ aiLabel = JSON.parse(this.markItem.label.replace(/'/g, '"'));
|
|
|
}
|
|
|
- this.rectangles = []
|
|
|
- console.log('00000',aiLabel)
|
|
|
+ this.rectangles = [];
|
|
|
+ console.log('00000', aiLabel);
|
|
|
aiLabel.forEach((item, index) => {
|
|
|
for (let key in item) {
|
|
|
- const [startX, startY, endX, endY] = item[key]
|
|
|
- const text = this.pestLibrary[key]
|
|
|
+ const [startX, startY, endX, endY] = item[key];
|
|
|
+ const text = this.pestLibrary[key];
|
|
|
if (!this.colorMap[text]) {
|
|
|
- this.colorMap[text] = colorList[this.colorIndex % colorList.length]
|
|
|
- this.colorIndex += 1
|
|
|
+ this.colorMap[text] =
|
|
|
+ colorList[this.colorIndex % colorList.length];
|
|
|
+ this.colorIndex += 1;
|
|
|
if (this.colorIndex >= colorList.length) {
|
|
|
- this.colorIndex = 0
|
|
|
+ this.colorIndex = 0;
|
|
|
}
|
|
|
}
|
|
|
this.rectangles.push({
|
|
|
@@ -485,22 +486,22 @@ export default {
|
|
|
endX: endX * this.imageScale,
|
|
|
endY: endY * this.imageScale,
|
|
|
color: this.colorMap[text],
|
|
|
- imageScale: this.imageScale
|
|
|
- })
|
|
|
+ imageScale: this.imageScale,
|
|
|
+ });
|
|
|
}
|
|
|
- })
|
|
|
- this.originDataLength = this.rectangles.length
|
|
|
+ });
|
|
|
+ this.originDataLength = this.rectangles.length;
|
|
|
} else {
|
|
|
// 人工标注,取mark
|
|
|
- console.log('this.colorIndex', this.colorIndex)
|
|
|
- this.rectangles = []
|
|
|
+ console.log('this.colorIndex', this.colorIndex);
|
|
|
+ this.rectangles = [];
|
|
|
this.markItem.mark.map((item, index) => {
|
|
|
- const { startX, startY, width, height, text } = item
|
|
|
+ const { startX, startY, width, height, text } = item;
|
|
|
if (!this.colorMap[text]) {
|
|
|
- this.colorMap[text] = colorList[this.colorIndex % colorList.length]
|
|
|
- this.colorIndex += 1
|
|
|
+ this.colorMap[text] = colorList[this.colorIndex % colorList.length];
|
|
|
+ this.colorIndex += 1;
|
|
|
if (this.colorIndex >= colorList.length) {
|
|
|
- this.colorIndex = 0
|
|
|
+ this.colorIndex = 0;
|
|
|
}
|
|
|
}
|
|
|
this.rectangles.push({
|
|
|
@@ -508,39 +509,40 @@ export default {
|
|
|
text: text,
|
|
|
startX: Number(startX) * this.markScale,
|
|
|
startY: Number(startY) * this.markScale,
|
|
|
- endX: Number(startX) * this.markScale + Number(width) * this.markScale,
|
|
|
- endY: Number(startY) * this.markScale + Number(height) * this.markScale,
|
|
|
+ endX:
|
|
|
+ Number(startX) * this.markScale + Number(width) * this.markScale,
|
|
|
+ endY:
|
|
|
+ Number(startY) * this.markScale + Number(height) * this.markScale,
|
|
|
color: this.colorMap[text],
|
|
|
- imageScale: this.imageScale
|
|
|
- })
|
|
|
- })
|
|
|
- this.originDataLength = this.rectangles.length
|
|
|
+ imageScale: this.imageScale,
|
|
|
+ });
|
|
|
+ });
|
|
|
+ this.originDataLength = this.rectangles.length;
|
|
|
}
|
|
|
- console.log('原始rectangles', this.rectangles)
|
|
|
+ console.log('原始rectangles', this.rectangles);
|
|
|
},
|
|
|
// 保存标注
|
|
|
saveLabel() {
|
|
|
- this.$emit('saveLabel', this.getData())
|
|
|
+ this.$emit('saveLabel', this.getData());
|
|
|
},
|
|
|
async getAllPestList() {
|
|
|
- const res = await this.$myRequest({
|
|
|
- url: '/api/api_gateway?method=forecast.pest_info.pest_dict',
|
|
|
- data: {
|
|
|
- type_name: this.typeName
|
|
|
- }
|
|
|
- })
|
|
|
- // console.log('获取到的病虫害数据', res)
|
|
|
- this.pestLibrary = res
|
|
|
- this.initCanvas()
|
|
|
+ const res = await this.$myRequest({
|
|
|
+ url: '/api/api_gateway?method=forecast.pest_info.pest_dict',
|
|
|
+ data: {
|
|
|
+ type_name: this.typeName,
|
|
|
+ },
|
|
|
+ });
|
|
|
+ // console.log('获取到的病虫害数据', res)
|
|
|
+ this.pestLibrary = res;
|
|
|
+ this.initCanvas();
|
|
|
},
|
|
|
-
|
|
|
- }
|
|
|
-}
|
|
|
+ },
|
|
|
+};
|
|
|
</script>
|
|
|
|
|
|
<style lang="less" scoped>
|
|
|
@primary-color: #018b3f !important;
|
|
|
-/deep/ .el-button--primary {
|
|
|
+::v-deep .el-button--primary {
|
|
|
background-color: @primary-color !important;
|
|
|
}
|
|
|
.canvas-container {
|