在图片中截取一部分区域的图片
使用html2canvas转图片太慢,最后改为使用canvas
截取
<template>
<div>
<el-dialog title="请在图片上画出需要新增故障的位置" :visible.sync="dialogVisible" width="1270px" :before-close="handleClose" :close-on-click-modal="false" :close-on-press-escape="false">
<div>
<img id="newImg" ref="newImg" style="user-select:none;" crossOrigin="Anonymous" :src="ftp+info.detectionImgLocation" width="1200" height="700" />
<canvas ref="myCanvas" class="myCanvas" width="1200" height="700"></canvas>
</div>
<!-- loading层,在上一层进行loading会导致canvas偏移的情况 -->
<div v-if="loading" v-loading="loading" class="loading_c" element-loading-text="截图中...."></div>
</el-dialog>
</div>
</template>
<script>
//import html2canvas from "html2canvas";
export default {
props: ['info'],
data() {
return {
dialogVisible: true,
ftp: process.env.VUE_APP_FTP_API,
originalImg: {
width: 0,
height: 0
},
canvas: "",
mousedownPostion: {
x: 0,
y: 0
},
finallyRect: {
x: "",
y: "",
width: 0,
height: 0
},
isDrawing: false,//是否开启绘制
loading: true
}
},
mounted() {
this.$nextTick(() => {
this.getImgWidth()
})
},
methods: {
//关闭弹窗
handleClose() {
this.$emit('closeAdd');
},
//画布监听
getImgWidth() {
const myCanvas = this.$refs.myCanvas
const img = new Image()
img.src = this.ftp + this.info.detectionImgLocation
img.onload = () => { //获取图片原始的长宽
this.originalImg.width = img.width
this.originalImg.height = img.height
this.loading = false
}
myCanvas.onmousedown = this.mouseDown
// myCanvas.onmousemove = this.mouseMove
myCanvas.onmouseup = this.mouseUp;
myCanvas.onmouseout = this.mouseOut;
this.canvas = myCanvas
},
//鼠标按下
mouseDown(e) {
this.mousedownPostion.x = e.offsetX
this.mousedownPostion.y = e.offsetY
this.isDrawing = true
this.canvas.onmousemove = this.mouseMove
},
//鼠标移动
mouseMove(e) {
if (!this.isDrawing) return false
let rectWidth = 0
let rectHeight = 0;
rectWidth = Math.abs(this.mousedownPostion.x - e.offsetX)
rectHeight = Math.abs(this.mousedownPostion.y - e.offsetY)
if (this.mousedownPostion.x - e.offsetX > 0 || this.mousedownPostion.y - e.offsetY > 0) {
//从右下往左上画
this.drawReat(e.offsetX, e.offsetY, rectWidth, rectHeight)
} else {
this.drawReat(this.mousedownPostion.x, this.mousedownPostion.y, rectWidth, rectHeight)
}
},
//鼠标抬起
mouseUp(e) {
if (!this.isDrawing) return false;
this.isDrawing = false
this.loading = true
this.canvas.onmousemove = function () { }
this.shareHandle()
},
//超出canvas
mouseOut(e) {
if (!this.isDrawing) return false;
this.isDrawing = false
this.loading = true
this.canvas.onmousemove = function () { }
this.shareHandle()
},
//绘制矩形
drawReat(x, y, width, height) {
this.finallyRect = {
x: x,
y: y,
width: width,
height: height
}
const context = this.canvas.getContext("2d")
context.clearRect(0, 0, 1200, 700)
context.save() //状态的保存
context.beginPath()
context.strokeStyle = '#fff'
context.lineWidth = 2
context.strokeRect(x, y, width, height)
context.restore() //状态的恢复
},
// 截图
async shareHandle() {
if (this.finallyRect.width <= 0 || this.finallyRect.height <= 0) {
this.loading = false
return false
}
//html2canvas截图,速度太慢改为原生截图
// 使用截取指定范围元素
// const opts = {
// useCORS: true,
// ...this.finallyRect
// };
// const canvas = await html2canvas(this.$refs.newImg, opts);
// const screenshotImage = canvas.toDataURL("image/jpg");
// // 图片在这里进行传输
// const scalX = this.originalImg.width / 1200
// const scalY = this.originalImg.height / 700
// this.finallyRect = {
// x: this.finallyRect.x * scalX,
// y: this.finallyRect.y * scalY,
// width: this.finallyRect.width * scalX,
// height: this.finallyRect.height * scalY
// }
// this.loading = false
// this.$emit('screenshotImage', {
// image: screenshotImage,
// ...this.finallyRect,
// picInfo: this.info
// });
//缩放比例
const scalX = this.originalImg.width / 1200
const scalY = this.originalImg.height / 700
this.finallyRect = {
x: this.finallyRect.x * scalX,
y: this.finallyRect.y * scalY,
width: this.finallyRect.width * scalX,
height: this.finallyRect.height * scalY
}
// 创建一个新的canvas
const canvasElement = document.createElement("canvas");
const canvasContext = canvasElement.getContext("2d");
const { x, y, width, height } = this.finallyRect
canvasElement.width = width;
canvasElement.height = height;
// 框选区域绘制到canvas里
canvasContext.drawImage(document.getElementById('newImg'),
x, y, width, height,
0, 0, width, height);
// 转为base64进行显示
const screenshotImage = canvasElement.toDataURL("image/jpeg");
this.loading = false
this.$emit('screenshotImage', {
image: screenshotImage,
...this.finallyRect,
picInfo: this.info
});
},
},
}
</script>
<style scoped>
.doCanvas {
position: absolute;
left: 0;
top: 13px;
z-index: 50;
}
::v-deep .el-dialog {
margin-top: 8vh !important;
}
::v-deep .el-dialog__body {
position: relative;
}
.myCanvas {
position: absolute;
left: 20px;
user-select: none;
}
.loading_c {
width: 1200px;
height: 700px;
top: 30px;
position: absolute;
}
</style>