需求: PC端裁剪屏幕
想法: 首先把屏幕当成一张图片,再去裁剪
1.首先需要下载两个插件
npm install html2canvas –save-dev // 生成图片
npm install vue-cropper –save-dev // 裁剪工具
2.开始操作
1.生成图片转换成blob-裁剪工具已准备
// 使用html2canvas保存屏幕生成图片
html2canvas(this.$refs.imageWrapper).then(canvas => {
// 这里会返回一个base64但是我需要blob
let dataURL = canvas.toDataURL("image/png");
// 开始把base64转成blob
let base64 = dataURL.split(',')[1];
// 转码第一次html2canvas返回base64转成blob
base64ToBlob({b64data: base64, contentType: 'image/png'}).then(res => {
// 转后后的blob对象-赋值给vue-cropper-裁剪工具
this.option.img = res.preview;
// 把裁剪图片覆盖屏幕-因为屏幕会闪一下所以采用了定时器(还是没用,笑死)
setTimeout(() => {
let element = document.querySelector('.vue-cropper');
element.style.zIndex = 2;
}, 100);
})
});
// 把base64转换为blob
function base64ToBlob ({b64data = '', contentType = '', sliceSize = 512} = {}) {
return new Promise((resolve, reject) => {
// 使用 atob() 方法将数据解码
let byteCharacters = atob(b64data);
let byteArrays = [];
for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
let slice = byteCharacters.slice(offset, offset + sliceSize);
let byteNumbers = [];
for (let i = 0; i < slice.length; i++) {
byteNumbers.push(slice.charCodeAt(i));
}
// 8 位无符号整数值的类型化数组。内容将初始化为 0。
// 如果无法分配请求数目的字节,则将引发异常。
byteArrays.push(new Uint8Array(byteNumbers));
}
let result = new Blob(byteArrays, {
type: contentType
})
result = Object.assign(result,{
// 这里一定要处理一下 URL.createObjectURL
preview: URL.createObjectURL(result),
name: `XXX.png`
});
imgInfo = result;
resolve(result)
})
}
// 这里下面是url转base64的方法------------------------------------------
// 需要用到再使用-我没用到
let imgUrL = `http://XXX.jpg`
urlToBase64(imgUrL).then(res => {
// 转化后的base64图片地址
console.log('base64', res)
})
function urlToBase64(url) {
return new Promise ((resolve,reject) => {
let image = new Image();
image.onload = function() {
let canvas = document.createElement('canvas');
canvas.width = this.naturalWidth;
canvas.height = this.naturalHeight;
// 将图片插入画布并开始绘制
canvas.getContext('2d').drawImage(image, 0, 0);
// result
let result = canvas.toDataURL('image/png')
resolve(result);
};
// CORS 策略,会存在跨域问题https://stackoverflow.com/questions/20424279/canvas-todataurl-securityerror
image.setAttribute("crossOrigin",'Anonymous');
image.src = url;
// 图片加载失败的错误处理
image.onerror = () => {
reject(new Error('urlToBase64 error'));
};
}
// 这里下面是base64转blob的方法------------------------------------------
// 需要用到再使用-我没用到
blobToBase64(blob).then(res => {
// 转化后的base64
console.log('base64', res)
})
blobToBase64(blob) {
return new Promise((resolve, reject) => {
const fileReader = new FileReader();
fileReader.onload = (e) => {
resolve(e.target.result);
};
// readAsDataURL
fileReader.readAsDataURL(blob);
fileReader.onerror = () => {
reject(new Error('blobToBase64 error'));
};
});
}
裁剪工具配置
<vueCropper
ref="cropper"
:img="option.img"
:outputSize="option.size"
:outputType="option.outputType"
:info="true"
:full="option.full"
:canMove="option.canMove"
:canMoveBox="option.canMoveBox"
:original="option.original"
:autoCrop="option.autoCrop"
:fixed="option.fixed"
:fixedNumber="option.fixedNumber"
:centerBox="option.centerBox"
:infoTrue="option.infoTrue"
:fixedBox="option.fixedBox"
:canScale="option.canScale"
v-if="isVueCropper"
></vueCropper>
option: {
img: '', // 裁剪图片的地址
info: true, // 裁剪框的大小信息
outputSize: 0.8, // 裁剪生成图片的质量
outputType: 'jpeg', // 裁剪生成图片的格式
canScale: false, // 图片是否允许滚轮缩放
autoCrop: false, // 是否默认生成截图框
// autoCropWidth: 300, // 默认生成截图框宽度
// autoCropHeight: 200, // 默认生成截图框高度
fixedBox: false, // 固定截图框大小 不允许改变
fixed: false, // 是否开启截图框宽高固定比例
fixedNumber: [7, 5], // 截图框的宽高比例
full: true, // 是否输出原图比例的截图
canMoveBox: true, // 截图框能否拖动
original: false, // 上传图片按照原始比例渲染
centerBox: false, // 截图框是否被限制在图片里面
infoTrue: true // true 为展示真实输出图片宽高 false 展示看到的截图框宽高
},
2. 开始裁剪
// 开始裁剪
this.$refs.cropper.startCrop(); // https://github.com/xyxiao001/vue-cropper 具体方法请查看官网
3. 确认裁剪
// 动态生成html确定按钮-根据需求制作
document.querySelector('.cropper-view-box').innerHTML += `<div style="color:#fff;text-align:right;line-height:25px;cursor:pointer;position: absolute;
bottom: -26px;
right: 0px;" id="joblist">确定</div>`;
// 裁剪页面获取base64再次转为blob-根据需求
document.getElementById('joblist').addEventListener('click', function (ev) {
// 获取截图的base64 数据
that.$refs.cropper.getCropData((data) => {
// do something
console.log(data)
let base64 = data.split(',')[1];
// 转码第二次截图返回base64转成blob提供给后端
base64ToBlob({b64data: base64, contentType: 'image/png'}).then(res => {
// 裁剪完成之后隐藏图片-显示屏幕
let element = document.querySelector('.vue-cropper');
element.style.zIndex = -1;
let div = document.getElementById('joblist');
document.querySelector('.cropper-view-box').removeChild(div);
})
})
});
版权声明:本文为Little_naive原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。