1. 需求描述
在视频中选定部分区域,然后将左上角坐标百分比和选定区域宽高所占百分比传给后端
2. 实现思路
- 播放 flv 格式视频
- 点击“截取”按钮,将视频当前画面截取为一张图片并回显图片,
- 使用 Cropper 插件截取图片部分区域(可以获取到截取图片左上角点坐标和截取部分的宽高)
3. 效果图展示
文章来源:https://www.toymoban.com/news/detail-435482.html
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官方地址 文章来源地址https://www.toymoban.com/news/detail-435482.html
到了这里,关于在视频中选定/截取部分区域画面,然后将左上角坐标百分比和选定区域宽高所占百分比传给后端的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!