Cropper.js实现对上传图片的剪裁

我实现的页面比较简单,主要就是点击按钮上传图片后,出现下图的截图页面。

先附上我使用时参考的文章,感谢作者大大🙏

前端图片处理(一) --- 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实现对上传图片的剪裁过程,欢迎大家点赞评论。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值