Untitled

 avatar
user_8000400
html
9 days ago
7.0 kB
4
Indexable
Never
import AppColors from '../../common/AppColors'
import { detect } from '../../common/utils/Detect'
import Logger from '../../common/utils/Logger'
import { getPixelMap, photoPickerGetUri } from '../../common/utils/PictureSaving'
import { showToast } from '../../common/utils/ToastUtils'
// 看看什么一个流程
@Component
export struct ImagePlaceHolder {
  @State isSubmit: boolean = false
  @State isDetect: boolean = false //控制检测结果显示区域的可见性
  @State detectResult: string = ``
  @State classes: string[] = [] //检测到的类别名称
  @State boxes: number[][] = [] //检测框的坐标
  @State scores: number[] = [] //置信度
  @State preImage: PixelMap = new Object() as PixelMap //存储预览图像的PixelMap对象

  // canvas参数
  private settings: RenderingContextSettings = new RenderingContextSettings(true)
  private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)
  @State canvasWidth: number = 0
  @State canvasHeight: number = 0

  //组件的UI结构
  build() {
    NavDestination() {
      Column() {
        Image(this.preImage)
          .alt($r('app.media.undraw_Images'))
          .width("100%")
          .autoResize(true)
          .backgroundColor($r("app.color.circle_color"))
          .borderRadius(25)

        Button() {
          Row() {
            if (this.isSubmit) {
              LoadingProgress().width(20).height(20).color(0xFFFFFF)
              Text('检测中……').fontSize(16).fontWeight(FontWeight.Bold).fontColor(0xFFFFFF)
            } else {
              Image($r("app.media.upload")).width(22).margin({ right: 10 })
              Text('上传图片').fontSize(16).fontWeight(FontWeight.Bold).fontColor(0xFFFFFF)
            }
          }
          .padding({
            left: 12,
            right: 12,
            top: 10,
            bottom: 10
          })
          .borderRadius(20)
        }
        .onClick(async () => {
          try {
            let uris = await photoPickerGetUri(1) //从图库中选择1张图片
            if (uris.length == 1) {
              this.isSubmit = true;
              Logger.info('picPicker: ' + uris[0]);
              this.preImage = await getPixelMap(uris[0]);

              let result = await detect(uris[0])
              // 检测失败
              if (result[0] != 0) {
                showToast('检测失败,请重试')
                return
              }
              // 检测成功
              this.isDetect = true
              this.isSubmit = false
              console.info('Results: ', JSON.stringify(result))
              console.info('detectResults: ', JSON.stringify(result[1]))
              // 更新状态以显示检测结果
              // detection_classes,detection_boxes,detection_scores
              this.detectResult = JSON.stringify(result[1], null, 2)
              this.classes = result[1].detection_classes
              this.boxes = result[1].detection_boxes
              this.scores = result[1].detection_scores
              console.info('classes: ', this.classes)
              console.info('boxes: ', this.boxes)
              console.info('scores: ', this.scores)

              showToast(`检测完成,共检测出${result[1].detection_classes.length}个缺陷`)
            } else {
              showToast('请选择一张PCB图片进行检测!')
            }
          } catch (err) {
            console.info('错误', err)
          }
        })
        .enabled(!this.isSubmit)
        .width(130)
        .height(50)
        .margin({ 'top': 30, 'bottom': 20 })
        .linearGradient({
          direction: GradientDirection.Right,
          colors: AppColors.gradient
        })

          if (this.isDetect) {
            Row() {
                Image($r("app.media.explorer")).width(20)
                Text('检测结果')
                  .margin({ 'bottom': 15 })
                  .width('90%')
                  .fontColor(0xFFFFFF)
                  .fontWeight(FontWeight.Bold)
                  .textAlign(TextAlign.Start)
            }.alignItems(VerticalAlign.Center).justifyContent(FlexAlign.Center).height(30)

                // 在图像上绘制检测框和显示检测结果
                Canvas(this.context)
                  .width('100%')
                    // .height(`${this.canvasHeight}px`)
                  .backgroundColor($r("app.color.circle_color"))
                  .onReady(() => {
                    if (this.isDetect) {
                      this.drawDetectionResults()
                    }
                  })
                  .onSizeChange((oldValue: SizeOptions, newValue: SizeOptions) => {
                    this.canvasWidth = Number(newValue.width)
                    this.canvasHeight = Number(newValue.height)
                  })
                TextArea({ text: this.detectResult }).width('90%').fontColor(0xFFFFFF)
              }
      }.width('100%').height('100%').backgroundColor($r("app.color.app_background"))
    }
  }
  // 绘制检测框和瑕疵信息(主要就是这一块不行)
  private async drawDetectionResults() {
    if (!this.preImage || this.boxes.length === 0) {
      return
    }
    const imageInfo = await this.preImage.getImageInfo();
    const imageWidth = imageInfo.size.width;
    const imageHeight = imageInfo.size.height;

    const containerWidth = this.canvasWidth // 假设你已经获取了父容器的宽度
    const aspectRatio = imageHeight / imageWidth

    this.canvasWidth = containerWidth
    this.canvasHeight = containerWidth * aspectRatio

    // 清空画布
    this.context.clearRect(0, 0, this.canvasWidth, this.canvasHeight)

    // 绘制图像(到这一步都是ok的)
    this.context.drawImage(this.preImage, 0, 0, this.canvasWidth, this.canvasHeight)

    // 设置字体和线条样式(从这里开始就不行了sos)你说有没有一种可能,这个字体和线条,被上面的图片覆盖了,有可能
    this.context.strokeStyle = 'red'
    this.context.lineWidth = 2
    this.context.font = '16px Arial'
    this.context.fillStyle = 'red'

    // 遍历每个检测框,绘制矩形和文本
    for (let i = 0; i < this.boxes.length; i++) {
      let box = this.boxes[i]
      let x1 = box[0] * this.canvasWidth
      let y1 = box[1] * this.canvasHeight
      let x2 = box[2] * this.canvasWidth
      let y2 = box[3] * this.canvasHeight
      let width = x2 - x1
      let height = y2 - y1

      // 绘制矩形框
      this.context.strokeRect(x1, y1, width, height)

      // 绘制文本 (瑕疵种类和置信度)
      let label = `${this.classes[i]}: ${Math.round(this.scores[i] * 100)}%`
      this.context.fillText(label, x1, y1 - 5)
    }
  }

  Element(arg0: string) {
    throw new Error('Function not implemented.')
  }
}
Leave a Comment