我实现的页面比较简单,主要就是点击按钮上传图片后,出现下图的截图页面。
先附上我使用时参考的文章,感谢作者大大🙏
前端图片处理(一) --- Cropper.js_sanye丶的博客-CSDN博客_cropper.js
文章中介绍的很仔细,这里就主要以我的项目为例做具体介绍。
1、安装
npm install cropperjs
2、使用
<template>
<div class="editView">
<!-- 底部上传按钮 -->
<div class="footerView">
<van-uploader :after-read="afterRead" :before-read="beforeRead" :max-size="5 * 1024 * 1024" @oversize="onOversize">
<van-button icon="plus" type="primary">点击上传图片</van-button>
</van-uploader>
</div>
<!-- 上传成功后出现图片裁剪框 -->
<van-overlay :show="cutShow" class="tailoringContainer">
<div class="wrapper" @click.stop>
<div class="imgContainer">
<img :src="staffPhoto ? staffPhoto : userImg" ref="image" alt="" />
</div>
<div class="changeImg">
<van-button color="#aaa" round type="info" @click="imgCloseBtn">取消</van-button>
<van-button color="#aaa" round type="info" @click="sureSava">完成</van-button>
</div>
</div>
</van-overlay>
</div>
</template>
<script>
import { Uploader, Button, Overlay, Toast } from 'vant';
import Cropper from "cropperjs";
import "cropperjs/dist/cropper.css";
export default {
data() {
return {
staffPhoto:'', //上传的图片
cutShow:false, //截图剪裁框
myCropper: null, //剪裁
userImg: require("../../assets/img/add.png"), //默认占位图
pageData:{
uploadPicImage:'' //接口返回的图片
} //接口数据
}
},
methods: {
// 上传图片
afterRead(file){
// 上传时先清空
this.staffPhoto = '';
if(this.myCropper){
this.myCropper.destroy()
}
// 获取上传的图片
this.staffPhoto = file.content;
// 剪裁
this.$refs.image.onload = () => {
this.init();
};
// 上传成功后隐藏剪裁页面
this.cutShow = true;
},
init(){
this.myCropper = new Cropper(this.$refs.image,{
viewMode:1, //显示模式 裁剪框在图片有效区内移动
dragNode:'move', //拖动模式 图片能拖动
aspectRatio:1, //裁剪框比例
background: false, //是否在容器上显示网格背景
autoCropArea: 0.8, //0-1之间的数值,定义自动剪裁框的大小默认值0.8
zoomOnWheel: true, //允许鼠标滚轴 缩放图片
movable: true, // 允许移动图片
zoomable: true, //允许缩放图片
zoomOnTouch: true, //允许触摸缩放图片
cropBoxResizable: true,//允许改变裁剪框大小
cropBoxMovable: true, //允许拖动裁剪框
touchDragZoom: true, //允许通过触摸移动来缩放图片
modal: true, //在剪裁框上显示黑色的模态窗口
})
// console.log(this.myCropper);
},
// 限制图片格式
beforeRead(file) {
if (file.type != 'image/png' && file.type != 'image/jpg' && file.type != 'image/jpeg') {
Toast('请上传png或jpg格式图片');
return false;
}
return true;
},
// 限制图片大小
onOversize(file){
Toast('图片大小不能超过 5Mb');
},
// 取消换图上传
imgCloseBtn(){
this.cutShow = false;
},
// 剪裁完成
sureSava(){
this.pageData.uploadPicImage = this.myCropper.getCroppedCanvas({
imageSmoothingQuality:'high'
}).toDataURL('image/png');
this.cutShow = false;
// 至此可获取裁剪后的图片(this.pageData.uploadPicImage),该图片为base64格式,后续可进行其他操作
},
},
}
</script>
<style lang="scss">
.cropper-container{
z-index: 999;
}
</style>
<style lang="scss" scoped>
.editView{
width: 100vw;
height: 100vh;
background-color: #333;
.footerView{
position: fixed;
bottom: 0;
left: 0;
width: 100vw;
height: 1rem;
}
.tailoringContainer{
width: 100vw;
height: 100vh;
background-color: rgba(000,000,000);
position: fixed;
top: 0;
left: 0;
z-index: 99;
.wrapper{
width: 100%;
height: 100%;
position: relative;
.imgContainer{
width: 100%;
height: 100%;
}
.changeImg{
width: 100vw;
position: fixed;
bottom: 1.2rem;
left: 0;
display: flex;
justify-content: space-between;
align-items: center;
z-index: 999;
}
}
}
}
</style>
到这里我们可以获取到裁剪后的图片了,在需要展示的地方使用就好,需要注意的是,我这里要将裁剪后的图片传给后端,后端需要文件流格式的图片,而我们裁剪后生成的图片为base64格式,这时可以转换一下
// base64图片转文件流
base64toFile(dataurl,filename){
let arr = dataurl.split(',');
let mime = arr[0].match(/:(.*?);/)[1];
let suffix = mime.split('/')[1];
let bstr = atob(arr[1]);
let n = bstr.length;
let u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new File([u8arr], `${filename}.${suffix}`, {
type: mime
});
},
使用时
// 上传图片文件
uploadPoster(photo){
let imgFile = this.base64toFile(photo);
// 由于项目中封装的请求方式报跨域不可用,所以使用XMLHttpRequest进行接口请求
let xhr = new XMLHttpRequest();
// 处理文件转换成formData格式
let formData = new FormData();
// 向接口传参,file为后端设置的参数字段,imgFile是转成文件流格式的图片,如果有其他参数也以这种形式传入
formData.append('file', imgFile);
xhr.open('POST', "后端提供的接口", true); // 第三个值指定接口是否异步
xhr.send(formData);
// 接口调用成功回调
xhr.onload = e => {
// 获取返回的数据,数据为字符串,需要使用JSON.parse()转换为JS对象
let responseData =JSON.parse(xhr.responseText);
console.log("responseData",responseData); // 打印responseData查看返回的数据格式,后续以responseData.XXX.XXX的形式获取指定字段的值
},
}
以上是本次使用Cropper.js实现对上传图片的剪裁过程,欢迎大家点赞评论。