template
<div class="right-box">
<div class="boxMide">
<div class="videoIcon">
<ul
class="tool-icons"
>
<li
class="icon-wrapper"
v-for="item in iconList"
:key="item.name"
:title="item.title"
@click="createdImg()"
>
<c-icon
:type="item.name"
citmsIcon
color="#2b2b2b"
></c-icon>
<p>截图</p>
</li>
</ul>
</div>
<c-icon type="shanchu_2" citmsIcon @click.native="close()" size="14px" class="guanbi" title="关闭" v-if="postData.device_uid"></c-icon>
<c-web-player :mimeCodec="mimeCodec" :httpuri="httpuri" :postData="postData"
:deviceName="deviceName"
ref="webPlayer" icon='video-camera'></c-web-player>
<div slot="screen-shot-info" class="screenShot-info" v-if="option.img">
<VueCropper ref="cropper" :img="option.img" :outputSize="option.size" :outputType="option.outputType" :info="option.info"
:full="option.full" :canMove="option.canMove" :canMoveBox="option.canMoveBox" :original="option.original"
:autoCrop="option.autoCrop" :autoCropWidth="option.autoCropWidth" :autoCropHeight="option.autoCropHeight"
:fixed="option.fixed" :fixedNumber="option.fixedNumber" :centerBox="option.centerBox"
:infoTrue="option.infoTrue" :fixedBox="option.fixedBox" @dblclick.native="getCropImage"
style="background-image:none"></VueCropper>
<div class="clean-btn" @click="cleanCrop">清除框选</div>
</div>
</div>
</div>
引入图片剪切工具
import { VueCropper } from 'vue-cropper'
data
data() {
return {
postData: {
action: '',
platform_uid: '',
device_uid: '',
trans_type: 'udp',
video: 'stream',
token: '456789',
connect_type: 'control'
},
httpuri: '',
deviceName: '',
mimeCodec: 'video/mp4; codecs="avc1.64001f"',
iconList: [{ title: '截图', name: 'jieping', isShow: true }],
save_url: '',
option: {
img: '', // 裁剪图片的地址
autoCropWidth: 300, // 默认生成截图框宽度
autoCropHeight: 300, // 默认生成截图框高度
info: true, // 裁剪框的大小信息
outputSize: 1, // 裁剪生成图片的质量
outputType: 'png', // 裁剪生成图片的格式
canScale: false, // 图片是否允许滚轮缩放
autoCrop: true, // 是否默认生成截图框
fixedBox: false, // 固定截图框大小 不允许改变
fixed: false, // 是否开启截图框宽高固定比例
fixedNumber: [7, 5], // 截图框的宽高比例
full: true, // 是否输出原图比例的截图
canMove: true, // 是否可以移动原图
canMoveBox: true, // 截图框能否拖动
original: false, // 上传图片按照原始比例渲染
centerBox: false, // 截图框是否被限制在图片里面
infoTrue: true // true 为展示真实输出图片宽高 false 展示看到的截图框宽高
}
}
},
methods:{
//截图
createdImg() {
let canvas = document.createElement('canvas')// 创建canvas标签
let canvasCtx = canvas.getContext('2d')
let video = document.getElementById(`web-video-canvas${this.$refs.webPlayer.postData.session_id}`)
// 设置canvas画布的宽和高,这一步很重要,决定截图是否完整
canvas.width = video.offsetWidth
canvas.height = video.offsetHeight
// 用drawImage方法将图片保存下来
canvasCtx.drawImage(video, 0, 0, canvas.width, canvas.height)
this.option.img = canvas.toDataURL('image/jpeg')// 将图片保存为base64格式
},
//鼠标双击后可以做一些业务处理,我这里是直接把截图后的base64上传后做其他逻辑处理
getCropImage() {
this.$refs.cropper.getCropData((data) => {
api.UploadBase64(data).then(res => {
const {code, result} = res
if (code == 0) {
this.$refs.joinModel.show(result)
}
})
})
},
//清除
cleanCrop() {
this.option.img = ''
}
}
css
.right-box{
width: calc(100vw - 352px);
height: 100%;
display: flex;
justify-content: center;
align-items: center;
.boxMide{
width: calc(100vw - 400px);
height: calc(100vh - 110px);
background: var(--background-color-base);
border-radius: 10px;
padding: 25px;
position: relative;
.guanbi{
position: absolute;
right: 10px;
top: 5px;
cursor: pointer;
color: var(--border-color-base);
}
.videoIcon{
position: absolute;
right: 40px;
top: 50%;
z-index: 9;
.tool-icons {
.icon-wrapper{
width: 50px;
height: 50px;
background: rgba(25, 30, 41, 0.8) !important;
cursor: pointer;
border-radius: 50%;
text-align: center;
border: 1px solid transparent;
i{
color: #fff !important;
margin-top:8px !important;
}
p{
font-size: 12px;
}
&:hover{
i{
color: var(--color-primary) !important;
}
border-color: var(--color-primary) !important;
}
}
}
}
.screenShot-info {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1;
.clean-btn {
position: absolute;
bottom: 60px;
right: 90px;
width: 81px;
border-radius: 4px;
font-size: 14px;
cursor: pointer;
text-align: center;
}
}
}
}
效果图