在视频中选定/截取部分区域画面,然后将左上角坐标百分比和选定区域宽高所占百分比传给后端

在视频中截取部分区域画面

1. 需求描述

在视频中选定部分区域,然后将左上角坐标百分比和选定区域宽高所占百分比传给后端

2. 实现思路

  1. 播放 flv 格式视频
  2. 点击“截取”按钮,将视频当前画面截取为一张图片并回显图片,
  3. 使用 Cropper 插件截取图片部分区域(可以获取到截取图片左上角点坐标和截取部分的宽高)

3. 效果图展示

在这里插入图片描述

在这里插入图片描述

4. 代码

<!-- 标定识别区域 -->
<template>
  <el-dialog
    title="标定识别区域"
    :visible.sync="dialogVisible"
    width="50%"
    @close="closeHandler"
    append-to-body
    :close-on-click-modal="false"
  >
    <video
      v-show="!imgSrc.length"
      id="videoElement"
      class="video-component"
      ref="videoElement"
      controls
      muted
    >
      不支持
    </video>
    <div v-if="!!imgSrc.length" class="imgBox">
      <img id="image" :src="imgSrc" alt="" />
    </div>

    <div class="btns">
      <el-button :disabled="!!imgSrc.length" type="primary" size="mini" @click="interceptHandler">
        截图
      </el-button>
      <el-button :disabled="!imgSrc.length" type="primary" size="mini" @click="imgSrc = ''">
        重新截图
      </el-button>
      <el-button :disabled="!imgSrc.length" type="primary" size="mini" @click="sureHandler">
        确定
      </el-button>
    </div>
  </el-dialog>
</template>

<script>
import flvjs from 'flv.js' // 用来处理 flv 格式视频
import html2canvas from 'html2canvas' // 用来截取视频当前画面为图片
import Cropper from 'cropperjs' // 截取图片部分区域工具
import 'cropperjs/dist/cropper.css' // 截取图片部分区域工具样式
import { updateRectf } from '@/api/video-intelligent-analysis.js' // 给后端传参接口

export default {
  name: 'SignAreaDialog',
  components: {},

  data() {
    return {
      dialogVisible: false,
      imgSrc: '', // 图片地址
      screenshotInfo: {
        // 裁剪信息
        x: 0, // 左上角点x轴坐标
        y: 0, // 左上角点y轴坐标
        width: 0, // 图片截取部分宽
        height: 0 // 图片截取部分高
      },
      rowData: {}, // 给后端接口传参时用到其中参数
      pRowData: {} // 给后端接口传参时用到其中参数
    }
  },

  computed: {},

  watch: {
    imgSrc: {
      handler(val) {
        let _this = this
        setTimeout(() => {
          if (!val) return

          /**** 【3】有图片 - 图片部分设定裁剪框 - 使用Cropper工具截取图片 ****/
          const image = document.getElementById('image')
          const cropper = new Cropper(image, {
            // aspectRatio: 839 / 473,
            // autoCropArea: 1, // 设置裁剪区域占图片的大小 值为 0-1 默认 0.8 表示 80%的区域
            // viewMode: 3, // 视图控制: 0 无限制;1 限制裁剪框不能超出图片的范围;2 限制裁剪框不能超出图片的范围 且图片填充模式为 cover 最长边填充;3 限制裁剪框不能超出图片的范围 且图片填充模式为 contain 最短边填充
            scalable: false, // 是否可以缩放图片(可以改变长宽) 默认true
            zoomable: false, // 是否可以缩放图片(改变焦距) 默认true
            zoomOnWheel: false, // 是否可以通过鼠标滚轮缩放图片 默认true
            crop(event) {
              Object.keys(_this.screenshotInfo).forEach((key) => {
                // 获取截取部分信息(event.detail中有左上角坐标、宽、高等属性)
                _this.screenshotInfo[key] = event.detail[key] < 0 ? 0 : event.detail[key]
              })

              // _this.screenshotInfo = event.detail
            }
          })
        }, 50)
      },
      deep: true,
      immediate: true
    }
  },

  mounted() {},

  created() {},

  methods: {
    open(type, rowData, pRowData, videoUrl) {
      this.rowData = rowData
      this.pRowData = pRowData

      // 用 setTimeout 延迟一下,否则获取不到 dom
      setTimeout(() => {
        /**** 【1】播放 flv 格式视频 ****/
        if (flvjs.isSupported()) {
          var videoElement = document.getElementById('videoElement')
          var flvPlayer = flvjs.createPlayer({
            type: 'flv',
            isLive: true,
            // url: 'ws://192.168.11.169:8866/live?url=D:/xgplayer-demo-720p.flv' // flv 视频地址
            url: videoUrl // flv 视频地址
          })
          flvPlayer.attachMediaElement(videoElement) // 获取不到 dom 的话这里会报错,使用延时器延时一下就好了
          flvPlayer.load()
          flvPlayer.play()
        }
      }, 50)

      this.dialogVisible = true
    },

    /**** 【2】点击“截取”按钮,将视频当前画面截取为一张图片 并 显示出来 ****/
    interceptHandler(event, ownerInstance) {
      html2canvas(document.getElementById('videoElement'), {
        backgroundColor: null,
        useCORS: true // 如果截图的内容里有图片,可能会有跨域的情况,加上这个参数,解决文件跨域问题
      }).then((canvas) => {
        let url = canvas.toDataURL('image/png')
        this.imgSrc = url
      })
    },

    sureHandler() {
      const container = document.querySelector('.cropper-container')
      const containerWidth = container.offsetWidth
      const containerHeight = container.offsetHeight

      let params = {
        sfbh: this.pRowData.id,
        znfxbh: this.rowData.znfxbh,
        // *1 是为了确保是数字之间进行运算,避免运算结果为 NAN
        rectfX: (((this.screenshotInfo.x * 1) / containerWidth) * 1).toFixed(7) * 1, // 识别区域 X 轴位置 百分比
        rectfY: (((this.screenshotInfo.y * 1) / containerHeight) * 1).toFixed(7) * 1, // 识别区域 Y 轴位置 百分比
        rectfW: (((this.screenshotInfo.width * 1) / containerWidth) * 1).toFixed(7) * 1, // 识别区域宽度百分比
        rectfH: (((this.screenshotInfo.height * 1) / containerHeight) * 1).toFixed(7) * 1 // 识别区域高度百分比
      }
      for (let key in params) {
        if (params[key] > 1) params[key] = 1
      }
      // return
      updateRectf(params).then((res) => {
        this.$common.CheckCode(res, '标定成功', () => {
          this.dialogVisible = false
          this.$emit('update')
        })
      })
    },

    closeHandler() {
      this.imgSrc = ''
      document.getElementById('videoElement').pause() // 暂停视频播放
      for (let key in this.screenshotInfo) {
        this.screenshotInfo[key] = 0
      }
    }
  }
}
</script>

<style lang='scss' scoped>
::v-deep .el-dialog__body {
  // display: flex;
  // justify-content: center;
  padding: 20px !important;
}
#videoElement {
  width: 100%;
}
// ::v-deep .cropper-bg {
//   width: 100% !important;
// }

.btns {
  margin-top: 10px;
  text-align: right;
}
</style>

cropperjs 参数配置文档
cropperjs npm官方地址

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值