最经我也是收到了这样一个需求,对监控进行截图加标注的需求,
我将自己的方法写在这里,希望能帮助各位小伙伴
1.首先监控类似于正在播放的视频,视频播放的帧太快了,所以一般直接使用插件进行截图会出现白屏或者,黑屏的情况,
2.所以只能是先对视频进行截图,然后再去加标注,或者使用canvas,绘画,来实现,但是如果标注方法过多,自己写不太现实,所以标注环节,我们使用插件,来完成,
1.先截屏,上代码
<template>
<div>
<div>
<div>
<video id="myPlayer1" width="70%" height="70%" controls>
<source src="../assets/video/movie.mp4" type="video/mp4" />
</video>
</div>
<div><el-button @click="getCurPic">截屏</el-button></div>
</div>
<!-- //绘制的地方 -->
<el-dialog :fullscreen="true" :visible.sync="cropperModel" width="80%">
<div class="cur_canvas_container">
<canvas
id="myCanvas"
:width="canvasWidth"
:height="canvasHeight"
class="cur_canvas"
></canvas>
<div><el-button @click="screenShot">批注</el-button></div>
</div>
</el-dialog>
<div>
<canvas id="loadingbar" style="width:200px; height:100px"></canvas>
</div>
</div>
</template>
methods: {
// 第一步截图
getCurPic() {
// 裁剪图片
this.cropperModel = true;
this.$nextTick(() => {
//需要使用nextTick 不然DOM渲染过快导致初次无法进行渲染-或者使用SetTomeOut(()=>{},200)
this.photograph();
});
},
photograph() {
// 把当前视频帧内容渲染到canvas上
let img = document.getElementById("myPlayer1"); //获取标签
let width = img.clientWidth; //获取屏幕尺寸
let height = img.clientHeight;
this.canvasWidth = width;
this.canvasHeight = height;
//getContext方法返回一个用于在画布上绘图的环境。
let canvas = document.getElementById("myCanvas");
// canvas.setAttribute("crossOrigin",'Anonymous')
let ctx = canvas.getContext("2d");
this.$nextTick(() => {
ctx.drawImage(img, 0, 0, width, height); //在画布上定位图像
//加标注
this.screenShot();
});
},
}
2.加标注
下载插件
yarn add js-web-screen-shot
# or
npm install js-web-screen-shot --save
下载完看看依赖包,是否有它
import ScreenShort from "js-web-screen-shot";
screenShot() {
const screenShotHandler = new ScreenShort({
enableWebRtc: false, //是否显示选项框
level: 99999, //层级级别
completeCallback: this.callback,//标注完成的回调
closeCallback: this.closeFn,//取消标注的方法
// downLoadCallback: this.closeFn, 自己需要改的插件源码
});
},
标注完成,上传至后端
<!-- 模态框canvas -->
<MaskModal :visible="isMask">
<div class="teacherDetails" v-show="flage">
<canvas
id="myCanvas"
:width="canvasWidth"
:height="canvasHeight"
class="cur_canvas"
></canvas>
</div>
<div class="teacherDetails" v-show="!flage">
<div class="img_header">
<div>截图预览</div>
<div>
<i
class="el-icon-close"
size="medium "
@click="
isMask = false;
flage = true;
"
></i>
</div>
</div>
<div class="Pictureannotation">
<canvas id="loadingbar"></canvas>
</div>
<div class="photonote">
<div>
备注:<input
type="text"
class="annotation"
v-model="remarks"
placeholder="请添加图片备注(最多二十字)"
maxlength="20"
/>
</div>
<div>
<el-button type="primary" @click="ScreenshotRemarksComplete"
>完成</el-button
>
</div>
</div>
</div>
<!-- <div>
</div> -->
</MaskModal>
callback(base64data) {
var image = new Image();
image.src = base64data;
image.onload = () => {
this.convertImageToCanvas(image);
this.flage = false;
};
},
convertImageToCanvas(image) {
var canvas = document.getElementById("loadingbar");
canvas.width = image.width;
canvas.height = image.height;
canvas.getContext("2d").drawImage(image, 0, 0);
return canvas;
},
ScreenshotRemarksComplete() {
this.isMask = false;
this.flage = true;
if (this.network) {
var canvas = document.getElementById("loadingbar");
var url = canvas.toDataURL("image/jpeg");
let fil = this.base64toFile(url, "filename");
let formData = new FormData();
formData.append("img", fil);
const PictureInformation = {
desc: this.remarks,
imgHolder: JSON.parse(this.userData).userName,
roomName: this.videoRoomName,
};
//调接口
RoomPictureUpload(PictureInformation, formData).then((res) => {
this.$message({
type: "success",
message: "截图成功",
});
this.remarks = "";
});
} else {
this.UploadFailed = true;
// const TIME_COUNT = 3;
if (!this.timer) {
// this.countDown = TIME_COUNT;
this.timer = setInterval(() => {
if (this.countDown > 1 && this.countDown <= 3) {
//限制倒计时区间
this.countDown--;
} else {
clearInterval(this.timer); //删除定时器
this.timer = null;
this.UploadFailed = false;
this.countDown = 3;
}
}, 1000);
}
}
},
base64toFile(base, filename) {
var arr = base.split(",");
var mime = arr[0].match(/:(.*?);/)[1];
var suffix = mime.split("/")[1];
var bstr = atob(arr[1]);
var n = bstr.length;
var u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
//转换成file对象
return new File([u8arr], `${filename}.${suffix}`, { type: mime });
},