在图片上绘制一个区域

38 阅读1分钟

背景

  • 算法下发任务,人脸识别

  • 摄像头执行任务,存了一张抓拍图

  • web需要在这张抓拍图上绘制人脸区域

<!-- 告警图片 -->
<template>
  <div class="myContent">
    <div class="snap-wrapper" v-if="info.captureImage">
      <div class="compared-title">{{ $t('alarm.panorama') }}</div>
      <div class="img">
        <img
          class="alarmImg"
          @load="drawRectByUrl(info.boxList, info.captureImage)"
          @click="showImagesInViewer([info.captureImage])"
          :src="info.captureImage"
          alt=""
        />
      </div>
    </div>
  </div>
</template>
<script>
export default {
  props: {
    info: {
      type: Object,
      default: () => {},
    },
  },
  data() {
    return {
      noImg: require('@/assets/alarmImg/nosnap.png'),
      flag: false,
    }
  },
  methods: {
    drawRectByUrl(boxList, url) {
      if (this.flag) return // 只执行一次
      if (!boxList) return

      const img = new Image()
      img.setAttribute('src', url)
      img.setAttribute('crossorigin', 'anonymous') // 设置跨域,解决toDataURL失败

      const that = this
      img.onload = function () {
        const canvas = document.createElement('canvas')
        const ctx = canvas.getContext('2d')
        canvas.width = this.width
        canvas.height = this.height
        ctx.drawImage(img, 0, 0, canvas.width, canvas.height)

        ctx.strokeStyle = '#f00'
        boxList.forEach((v) => that.drawRect(ctx, v.box))

        const base64 = canvas.toDataURL('image/png')

        that.info.captureImage = base64
        that.flag = true
      }
    },
    drawRect(ctx, data) {
      ctx.beginPath()
      for (let i = 0; i < data.length; i++) {
        if (i == 0) {
          ctx.moveTo(data[i].x, data[i].y)
        } else {
          ctx.lineTo(data[i].x, data[i].y)
        }
      }
      ctx.closePath()
      ctx.stroke()
    },
    showImagesInViewer(urls) {
      urls instanceof Array && urls?.length && this.$viewerApi({ images: urls })
    },
  },
}
</script>