浏览代码

fix: 数据标注加载变更,修改页面显示

Suuuuuukang 10 月之前
父节点
当前提交
fac0be8e62

+ 1 - 0
src/components/ProForm/index.vue

@@ -29,6 +29,7 @@
             </template>
             <template v-else-if="item.compOptions.elTagName === 'img-upload'">
               <uploadImg v-model:image-url="formModel[item.prop]" />
+<!--              <el-button @click="() => {console.log(formModel[item.prop])}"/>-->
             </template>
 
             <template v-else-if="item.compOptions.elTagName === 'imgs-upload'">

+ 8 - 1
src/components/Upload/Img.vue

@@ -43,6 +43,11 @@
     <div class="el-upload__tip">
       <slot name="tip"></slot>
     </div>
+<!--    <el-dialog id="dialog" v-if="isShowData" :visible="imgViewVisible">-->
+<!--      <el-image-viewer :url-list="['/api' + imageUrl]" />-->
+<!--    </el-dialog>-->
+<!--    <el-image-viewer v-else-if="imgViewVisible" :url-list="['/api' + imageUrl]" @close="imgViewVisible = false" />-->
+
     <el-image-viewer v-if="imgViewVisible" :url-list="['/api' + imageUrl]" @close="imgViewVisible = false" />
   </div>
 </template>
@@ -64,6 +69,7 @@ interface UploadFileProps {
   height?: string // 组件高度 ==> 非必传(默认为 150px)
   width?: string // 组件宽度 ==> 非必传(默认为 150px)
   borderRadius?: string // 组件边框圆角 ==> 非必传(默认为 8px)
+  isShowData?: boolean
 }
 
 // 接受父组件参数
@@ -75,7 +81,8 @@ const props = withDefaults(defineProps<UploadFileProps>(), {
   fileType: () => ['image/jpeg', 'image/png', 'image/gif'],
   height: '150px',
   width: '150px',
-  borderRadius: '8px'
+  borderRadius: '8px',
+  isShowData: false
 })
 
 // 生成组件唯一id

+ 5 - 6
src/views/demo/components/img-detect.vue

@@ -39,8 +39,7 @@ const props = defineProps({
     type: Array
   },
   jsonData: {
-    type: String,
-    default: ''
+    type: Array
   }
 })
 const emit = defineEmits(['success'])
@@ -93,7 +92,7 @@ const onSubmit = () => {
   for (let i = 2; i < points.length; i++) {
     let label = points[i]['label']
     // console.log(label)
-    emitData.data += label + ', '
+    emitData.data += label + ' '
     let index = -1, yMin = 10000000, xMax = -1
     for (let j = 0; j < points[i]['nodes'].length; j++) {
       if (points[i]['nodes'][j].y < yMin) {
@@ -108,14 +107,14 @@ const onSubmit = () => {
 
     for (let j = 0; j < points[i]['nodes'].length; j++) {
       let ptr = (j + index) % points[i]['nodes'].length
-      emitData.data += points[i]['nodes'][ptr].x + ', ' + points[i]['nodes'][ptr].y
+      emitData.data += points[i]['nodes'][ptr].x + ' ' + points[i]['nodes'][ptr].y
       if (j + 1 !== points[i]['nodes'].length) {
-        emitData.data += ', '
+        emitData.data += ' '
       }
     }
 
     if (i + 1 !== points.length) {
-      emitData.data += '; '
+      emitData.data += ' \r\n'
     }
     // if ()
     // datas += points[i][]

+ 104 - 92
src/views/demo/components/img-maker.vue

@@ -57,8 +57,7 @@ const props = defineProps({
     type: Object
   },
   jsonData: {
-    type: String,
-    default: ''
+    type: Array
   }
 })
 const state = reactive({
@@ -183,21 +182,21 @@ const loadInit = () => {
 
   // nice try!
   // console.log(props.jsonData)
-  if (props.jsonData && props.jsonData.length > 0) {
-    // console.log('load')
-    state.canvas.loadFromJSON(props.jsonData, () => {
-      let objects = state.canvas.getObjects()
-      // console.log(objects)
-      objects[0].selectable = false
-      for (let i = 1; i < objects.length; i++) {
-        objects[i].selectable = true
-      }
-      state.canvas.renderAll()
-    })
-    // console.log(state.canvas)
-    state.loading = false
-    return
-  }
+  // if (props.jsonData && props.jsonData.length > 0) {
+  //   // console.log('load')
+  //   state.canvas.loadFromJSON(props.jsonData, () => {
+  //     let objects = state.canvas.getObjects()
+  //     // console.log(objects)
+  //     objects[0].selectable = false
+  //     for (let i = 1; i < objects.length; i++) {
+  //       objects[i].selectable = true
+  //     }
+  //     state.canvas.renderAll()
+  //   })
+  //   // console.log(state.canvas)
+  //   state.loading = false
+  //   return
+  // }
 
   let imgElement = new Image()
   imgElement.src = props.src
@@ -217,86 +216,92 @@ const loadInit = () => {
     state.realPoint.x = Math.floor(props.width / 2)
     state.realPoint.y = Math.floor(props.height / 2)
 
-    if (!(props.jsonData && props.jsonData.length > 0)) {
-      let imgInstance = new fabric.Image(imgElement, {
-        selectable: false,
-        width: imgElement.width,
-        height: imgElement.height,
-        scaleX: state.radio,
-        scaleY: state.radio
-      })
-      state.canvas.add(imgInstance)
-      drawImage()
+    let imgInstance = new fabric.Image(imgElement, {
+      selectable: false,
+      width: imgElement.width,
+      height: imgElement.height,
+      scaleX: state.radio,
+      scaleY: state.radio
+    })
+    state.canvas.add(imgInstance)
+    if (props.jsonData && props.jsonData.length > 0) {
+      for (let i = 0; i < props.jsonData.length; i++) {
+        let config = props.jsonData[i]
+        let obj = new fabric.Path(config.pathString, config)
+        state.canvas.add(obj)
+      }
       state.canvas.renderAll()
     }
     state.radio = state.canvas.getZoom()
     state.loading = false
+    // console.log(state.realRadioX)
+    // console.log(state.realRadioY)
   }
 }
-const drawImage = () => {
-  if (props.area === '') {
-    clearAll()
-    return
-  }
-  // console.log(props.area)
-  let points = props.area.split(',').map(item => {
-    let areas = item.split(';')
-    let data = areas.map((ars, index) => {
-      let arp = 0
-      let ar = Number(ars)
-      if (index % 2 == 0) {
-        let dx = Math.abs(state.realPoint.x > ar ? state.realPoint.x - ar : state.realPoint.x + ar) / state.realRadioX
-        let rdx = Math.abs(state.imgPoint.x - dx)
-        arp = rdx
-      } else {
-        let dy = Math.abs(state.realPoint.y > ar ? state.realPoint.y - ar : state.realPoint.y + ar) / state.realRadioY
-        let rdy = Math.abs(state.imgPoint.y - dy)
-        arp = rdy
-      }
-      return Number(arp) * state.radio
-    })
-    return data
-  })
-  points.forEach(point => {
-    drawImageObj(point)
-  })
-}
-const drawImageObj = data => {
-  let path = 'M '
-  // debugger
-  let points = [] as any
-  let len = data.length / 2
-  for (let i = 0; i < len; i++) {
-    let idx = i * 2
-    points.push({ x: data[idx], y: data[idx + 1] })
-    path += `${data[idx]} ${data[idx + 1]} L `
-  }
-  let canvasObject = null as any
-  if (points[0]?.y === points[1]?.y && points[2]?.y === points[3]?.y && points[0]?.x === points[3]?.x && points[1]?.x - points[2]?.x) {
-    path = path.replace(/L\s$/g, 'z')
-    canvasObject = new fabric.Path(path, {
-      left: data[0],
-      top: data[1],
-      stroke: state.color,
-      selectable: false,
-      strokeWidth: state.drawWidth,
-      fill: 'rgba(255, 255, 255, 0)',
-      hasControls: false
-    })
-  } else {
-    canvasObject = new fabric.Polygon(points, {
-      stroke: state.color,
-      strokeWidth: state.drawWidth,
-      fill: 'rgba(255, 255, 255, 0)',
-      opacity: 1,
-      hasBorders: false,
-      hasControls: false,
-      evented: false
-    })
-  }
-  canvasObject['points'] = points
-  state.canvas.add(canvasObject)
-}
+// const drawImage = () => {
+//   if (props.area === '') {
+//     clearAll()
+//     return
+//   }
+//   // console.log(props.area)
+//   let points = props.area.split(',').map(item => {
+//     let areas = item.split(';')
+//     let data = areas.map((ars, index) => {
+//       let arp = 0
+//       let ar = Number(ars)
+//       if (index % 2 == 0) {
+//         let dx = Math.abs(state.realPoint.x > ar ? state.realPoint.x - ar : state.realPoint.x + ar) / state.realRadioX
+//         let rdx = Math.abs(state.imgPoint.x - dx)
+//         arp = rdx
+//       } else {
+//         let dy = Math.abs(state.realPoint.y > ar ? state.realPoint.y - ar : state.realPoint.y + ar) / state.realRadioY
+//         let rdy = Math.abs(state.imgPoint.y - dy)
+//         arp = rdy
+//       }
+//       return Number(arp) * state.radio
+//     })
+//     return data
+//   })
+//   points.forEach(point => {
+//     drawImageObj(point)
+//   })
+// }
+// const drawImageObj = data => {
+//   let path = 'M '
+//   // debugger
+//   let points = [] as any
+//   let len = data.length / 2
+//   for (let i = 0; i < len; i++) {
+//     let idx = i * 2
+//     points.push({ x: data[idx], y: data[idx + 1] })
+//     path += `${data[idx]} ${data[idx + 1]} L `
+//   }
+//   let canvasObject = null as any
+//   if (points[0]?.y === points[1]?.y && points[2]?.y === points[3]?.y && points[0]?.x === points[3]?.x && points[1]?.x - points[2]?.x) {
+//     path = path.replace(/L\s$/g, 'z')
+//     canvasObject = new fabric.Path(path, {
+//       left: data[0],
+//       top: data[1],
+//       stroke: state.color,
+//       selectable: false,
+//       strokeWidth: state.drawWidth,
+//       fill: 'rgba(255, 255, 255, 0)',
+//       hasControls: false
+//     })
+//   } else {
+//     canvasObject = new fabric.Polygon(points, {
+//       stroke: state.color,
+//       strokeWidth: state.drawWidth,
+//       fill: 'rgba(255, 255, 255, 0)',
+//       opacity: 1,
+//       hasBorders: false,
+//       hasControls: false,
+//       evented: false
+//     })
+//   }
+//   canvasObject['points'] = points
+//   state.canvas.add(canvasObject)
+// }
 
 const selectLastObject = () => {
   let objects = state.canvas.getObjects()
@@ -788,7 +793,14 @@ const getData = () => {
             x: getPoint(aCoords[mark].x),
             y: getPoint(aCoords[mark].y)
           }
-          point['nodes'].push(getRealPoint(poi))
+          // console.log(poi)
+          poi = getRealPoint(poi)
+          // console.log(poi)
+          poi.x = poi.x / state.realRadioX / 1920
+          poi.y = poi.y / state.realRadioY / 1080
+          // console.log(poi)
+          point['nodes'].push(poi)
+          // point['nodes'].push(getRealPoint(poi))
         })
       }
       // if (item.points && item.points.length === 2) {

+ 72 - 44
src/views/demo/data/index.vue

@@ -2,7 +2,8 @@
   <div class="table-box">
     <ProTable ref="proTable" :columns="columns" row-key="id" :request-api="listDataApi" :init-param="initParam">
       <template #yuan="scope">
-        <el-image style="width: 100px" :src="'/api' + scope.row.url" @click="markImg(scope.row)" />
+        <uploadImg :is-show-data="true" :disabled="true" :image-url="scope.row.url" />
+<!--        <el-image style="width: 100px" :src="'/api' + scope.row.url" @click="markImg(scope.row)" />-->
       </template>
       <!-- 表格 header 按钮 -->
       <template #tableHeader="scope">
@@ -57,9 +58,10 @@ import ImportPicDataset from '@/components/ImportPicDataset/index.vue'
 import { ProTableInstance, ColumnProps } from '@/components/ProTable/interface'
 import { Delete, EditPen, Download, Upload, View, CirclePlus } from '@element-plus/icons-vue'
 // import { fabric } from 'fabric'
-import { useDrawArea } from '@/utils/fabric'
+// import { useDrawArea } from '@/utils/fabric'
 import { getDictsApi } from '@/api/modules/system/dictData'
 import ImgDetect from '../components/img-detect.vue'
+import uploadImg from '@/components/Upload/Img.vue'
 import {
   listDataApi,
   delDataApi,
@@ -76,11 +78,11 @@ import http from '@/api'
 
 onMounted (() => {
   state.cacheData.url = 'http://localhost:9090/profile/upload/2024/08/08/144745610/test.png'
-  handleImgSuccess({
-    data: 'test change data',
-    jsonData: 'jsonData12345 test change',
-    url: 'testurl'
-  })
+  // handleImgSuccess({
+  //   data: 'test change data',
+  //   jsonData: 'jsonData12345 test change',
+  //   url: 'testurl'
+  // })
 })
 
 const imgDetect = ref()
@@ -102,7 +104,7 @@ const state = reactive({
   //     label: 'car'
   //   }
   // ],
-  jsonData: '',
+  jsonData: [],
   cacheData: {}
     // '{"version":"5.3.0","objects":[{"type":"image","version":"5.3.0","originX":"left","originY":"top","left":0,"top":0,"width":918,"height":789,"fill":"rgb(0,0,0)","stroke":null,"strokeWidth":0,"strokeDashArray":null,"strokeLineCap":"butt","strokeDashOffset":0,"strokeLineJoin":"miter","strokeUniform":false,"strokeMiterLimit":4,"scaleX":0.68,"scaleY":0.68,"angle":0,"flipX":false,"flipY":false,"opacity":1,"shadow":null,"visible":true,"backgroundColor":"","fillRule":"nonzero","paintFirst":"fill","globalCompositeOperation":"source-over","skewX":0,"skewY":0,"cropX":0,"cropY":0,"src":"http://localhost:8848/api/profile/upload/2024/08/08/144745610/3-3.jpg","crossOrigin":null,"filters":[]},{"type":"rect","version":"5.3.0","originX":"left","originY":"top","left":181.38,"top":251.38,"width":244,"height":162,"fill":"rgba(255, 255, 255, 0)","stroke":"#E34F51","strokeWidth":5,"strokeDashArray":null,"strokeLineCap":"butt","strokeDashOffset":0,"strokeLineJoin":"miter","strokeUniform":false,"strokeMiterLimit":4,"scaleX":1,"scaleY":1,"angle":-25,"flipX":false,"flipY":false,"opacity":1,"shadow":null,"visible":true,"backgroundColor":"","fillRule":"nonzero","paintFirst":"fill","globalCompositeOperation":"source-over","skewX":0,"skewY":0,"rx":0,"ry":0}]}'
 })
@@ -125,6 +127,7 @@ const deleteData = async (params: any) => {
 const markImg = data => {
   // console.log(data)
   state.cacheData = data
+  state.jsonData = []
     if (!data.url || data.url.length === 0) {
     ElMessage.warning('缺失图像,暂时不能进行区域添加!')
     return
@@ -145,26 +148,56 @@ const markImg = data => {
           label: res.data.list[i].dictValue
         })
       }
+
+      if (state.cacheData.labelurl && state.cacheData.labelurl.length > 0) {
+        // console.log('get label jsonData')
+        http.get<any>(state.cacheData.labelurl)
+          .then(res => {
+            state.jsonData = []
+            console.log(res)
+            let arr = res.split('\r\n')
+            console.log(arr)
+            for (let i = 0; i < arr.length; i++) {
+              let subArr = arr[i].split(' ')
+              // console.log(subArr)
+              let cssVal = '#000000'
+              let label = '-1'
+              for (let j = 0; j < state.classes.length; j++) {
+                if (state.classes[j].label === subArr[0]) {
+                  cssVal = state.classes[j].color
+                  label = state.classes[j].label
+                  break
+                }
+              }
+              state.jsonData.push({
+                pathString: 'M ' + subArr[1] * 1920 + ' ' + subArr[2] * 1080 +
+                  ' L ' + subArr[3] * 1920 + ' ' + subArr[4] * 1080 +
+                  ' L ' + subArr[5] * 1920 + ' '  + subArr[6] * 1080 +
+                  ' L ' + subArr[7] * 1920 + ' '  + subArr[8] * 1080 +
+                  ' z',
+                // left: 0,
+                // top: 0,
+                fill: '',
+                stroke: cssVal,
+                strokeWidth: 5,
+                label: label
+              })
+            }
+            // console.log(state.jsonData)
+            imgDetect.value.visible = true
+          })
+          .catch(err => {
+            console.log(err)
+          })
+      } else {
+        imgDetect.value.visible = true
+      }
     })
     .catch(err => {
       console.log(err)
     })
 
   state.cover = '/api' + data.url
-  if (state.cacheData.labelurl && state.cacheData.labelurl.length > 0) {
-    // console.log('get label jsonData')
-    http.get<any>(state.cacheData.labelurl.split(';')[1])
-      .then(res => {
-        // console.log(res)
-        state.jsonData = JSON.stringify(res)
-        imgDetect.value.visible = true
-      })
-      .catch(err => {
-        console.log(err)
-      })
-  } else {
-    imgDetect.value.visible = true
-  }
 
   // area 代表后端的传来的标注数据
   // console.log(state.cover)
@@ -203,38 +236,33 @@ const handleImgSuccess = data => {
 
   state.cacheData.increment = 'NONE'
 
-  let arr = state.cacheData.url.split('upload/')
+  let arr = state.cacheData.url.split('upload')
+  // console.log(arr)
   let filenames = (arr[arr.length - 1]).split('.')
   filenames[filenames.length - 1] = 'txt'
   // console.log(filenames.join('.'))
   let filename = filenames.join('.')
+  filename = filename.replace(/\\/g, "/")
+  if (filename.startsWith('/')) {
+    filename = filename.substring(1)
+  }
+  // console.log(filename)
 
   labelFile(data['data'], filename)
     .then(res => {
       // console.log(res)
       if (res.code === 200) {
         state.cacheData.labelurl = res.data.url
-
-        filenames[filenames.length - 2] += '_json'
-        filename = filenames.join('.')
-        setTimeout(() => {
-          labelFile(data['jsonData'], filename)
-            .then(res => {
-              if (res.code === 200) {
-                state.cacheData.labelurl += ';' + res.data.url
-                updateDataApi(state.cacheData)
-                  .then(res => {
-                    // console.log(res)
-                    if (res.data) {
-                      ElMessage.success('操作成功')
-                    }
-                  })
-                  .catch(err => {
-                    console.log(err)
-                  })
-              }
-            })
-        }, 1200)
+        updateDataApi(state.cacheData)
+          .then(res => {
+            // console.log(res)
+            if (res.data) {
+              ElMessage.success('操作成功')
+            }
+          })
+          .catch(err => {
+            console.log(err)
+          })
       }
     })