vue之使用Cropper进行图片剪裁上传

在项目中,对上传的图片按照比例和尺寸进行裁剪,以便于应用到不同的场景和平台上。这里采用cropper插件裁剪图片

一、cropper的使用
使用教程:https://github.com/fengyuanchen/cropper#options

二、用例:

点击头像上传图片→对图片进行裁剪


源码

<template>
    <div class="index_seting">
        <ul class="set_center">
            <li class="set_head_img">
                <a class="set_item">
                    <label class="head_lab" for="change">
                        <h3>头像</h3>
                        <span class="head_img">
                            <img :src="set_head">
                        </span>
                    </label>
                    <input type="file" id="change" class="none" @change="change" accept="image/png, image/jpeg, image/gif, image/jpg" multiple>
                </a>
            </li>
        </ul>
        <div class="img-view" v-show="img_cro_model" >
            <img id="image" :src="url" alt="Picture">
            <div class="gif_loading" v-show="update_img">
                <p>头像上传中...</p>
                <span></span>
            </div>
            <div class="img_btn">
                <span @click="hideImageCro">取消</span>
                <span @click="doCrop">完成</span>
            </div>
        </div>
    </div>
</template>

<script>
import Cropper from 'cropperjs'
export default {
  data () {
    return {
        set_head:'',                //头像图片临时缓存url
        update_img:false,           //头像上传中gif
        picValue:'',                //图片参数
        cropper:'',  
        croppable:false,            //是否初始化裁剪框
        img_cro_model:false,        //是否显示底部头像裁剪模块  
        url:'',                     //每次替换图片要重新得到新的url
        base64:''                   //裁剪并压缩后的图片
    }
  },
  mounted:function(){
    //初始化裁剪框  
    var self = this;
    var image = document.getElementById('image');  
    this.cropper = new Cropper(image, {  
        aspectRatio: 1,  
        viewMode: 1,  
        background:false,  
        zoomable:false,  
        ready: function () {  
            self.croppable = true;
        }  
    });
  },
  methods:{
    hideImageCro(){
        this.img_cro_model = false;
    },
    //让浏览器执行createObjectURL方法,实现本地图片预览
    getObjectURL (file) {  
        var url = null ;
        if (window.createObjectURL!=undefined) {    // basic  
            url = window.createObjectURL(file);  
        } else if (window.URL!=undefined) {         // firefox
            url = window.URL.createObjectURL(file);  
        } else if (window.webkitURL!=undefined) {   // chrome  
            url = window.webkitURL.createObjectURL(file);  
        }  
        return url;
    },  
    change (e) {  
        let files = e.target.files || e.dataTransfer.files;  
        if (!files.length) return;
        this.picValue = files[0];  
        this.url = this.getObjectURL(this.picValue);  
        //每次替换图片要重新得到新的url  
        if(this.cropper){
            this.cropper.replace(this.url);  
        }  
        this.img_cro_model = true;  
    },
    //强制让crop函数在弹窗后执行
    doCrop(){
        let that = this;
        this.update_img = true;
        setTimeout(function(){
            that.crop();
        },10);
    }, 
    crop () {  
        var croppedCanvas;  
        var roundedCanvas;  
        if (!this.croppable) {  
          return;  
        }  
        //裁剪
        croppedCanvas = this.cropper.getCroppedCanvas();  
        //圆
        roundedCanvas = this.getRoundedCanvas(croppedCanvas);  
        //将裁剪后的base64图片做压缩处理        
        this.compressImg(roundedCanvas.toDataURL());
    },  
    getRoundedCanvas (sourceCanvas) {
        var canvas = document.createElement('canvas');  
        var context = canvas.getContext('2d');  
        var width = sourceCanvas.width;  
        var height = sourceCanvas.height;  
        canvas.width = width;  
        canvas.height = height;  
        context.imageSmoothingEnabled = true;
        context.drawImage(sourceCanvas, 0, 0, width, height);  
        context.globalCompositeOperation = 'destination-in';  
        context.beginPath();  
        //取消输出图片的圆形截取效果
        // context.arc(width / 2, height / 2, Math.min(width, height) / 2, 0, 2 * Math.PI, true);  
        context.fill();  
        return canvas;
    },
    compressImg(img_base64){
        let that = this,
            Img = new Image();
        Img.src = img_base64;
        Img.onload = function(){
            let w = this.naturalWidth,
                h = this.naturalHeight,
                resizeW = 0,
                resizeH = 0;
            //压缩设置
            let maxSize = {
                width:320,
                height:320,
                level:0.6      //图片保存质量
            };
            //计算压缩比例
            if(w > maxSize.width || h > maxSize.height){
                let multiple = Math.max(w / maxSize.width , h / maxSize.height);
                resizeW = w / multiple;
                resizeH = h / multiple; 
            }else{
                resizeW = w;
                resizeH = h;
            }
            let canvas = document.createElement("canvas"),
                ctx = canvas.getContext('2d');
            //ios手机拍照会旋转90度,这里做处理
            if(window.navigator.userAgent.indexOf('iphone') > 0){
                canvas.width = resizeH;
                canvas.height = resizeW;
                ctx.retate(90 * Math.PI / 180);
                ctx.drawImage(Img,0,-resizeH,resizeW,resizeH);
            }else{
                canvas.width = resizeW;
                canvas.height = resizeH;
                ctx.drawImage(Img,0,0,resizeW,resizeH);
            }
            that.base64 = canvas.toDataURL('image/jpeg',maxSize.level);
            that.$http.post('/hnwfx/setDaoGouInfo',{file:that.base64},{'headers':{'Content-Type':'application/json'}}).then(function(res){
                that.update_img = false;
                that.img_cro_model = false;
                that.set_head = that.base64;
            }); 
        }
    }
  }
}
</script>

<style scoped src="./seting.css"></style>
@charset "utf-8";

.index_seting .set_center{
	width:100%;
	background-color: #fff;
}
.index_seting .set_center li{
	position: relative;
}
.set_center li .set_item{
	display: block;
	margin: 0 0.426667rem;
	overflow: hidden;
	background: url(./arrow.png) right center no-repeat transparent;
	background-size: 4% auto;
}
.set_center li .set_item .head_lab{
	width:100%;
	height: 100%;
	display: block;
	overflow: hidden;
}
.set_center li .set_item span{
	position: absolute;
	right:1.408rem;
	font-size: 0.554667rem;
	color:#666;
	display: inline-block;
}
.set_center li .set_item .head_img{
	width:2.730667rem;
	height: 2.730667rem;
	display: inline-block;
	margin:0.362667rem 0;
    border-radius: 50%;
    overflow: hidden;
}
.set_center li .set_item .head_img img{
	width:100%;
	height: 100%;
}
.index_seting .set_center li h3{
	float:left;
	font-size: 0.597333rem;
	font-weight: normal;
	color:#000;
}
.index_seting .set_center li:after{
    position:absolute;
    bottom:-1px;
    left:0px;
    content:'';
    width:100%;
    height:1px;
	border-top:1px solid #e4e4e4; 
    -webkit-transform:scaleY(0.5);
}
.set_center .set_head_img{
	line-height: 3.456rem;
}
.img-view{
	width:100%;
	height: 100%;
	position: fixed;
	bottom:0;
	background: rgba(0, 0, 0, 1);
	z-index: 1000;
}
.gif_loading{
	width:6.4rem;
	height: 4.266667rem;
	position: fixed;
	top:50%;
	left:50%;
	margin-top: -2.133333rem;
	margin-left: -3.2rem;
	background-color: #fff;
	border-radius: 10px;
	text-align: center;
	box-shadow: 0px 0px 1px 1px #e6e6e6;
}
.gif_loading p{
	margin-top:1.066667rem;
	font-size: 0.64rem;
}
.gif_loading span{
	display: inline-block;
	width:66px;
	height: 6px;
	background:url(./seting01.gif) center center no-repeat;
	background-size: 100% auto;
}
.img_btn{
	width:100%;
	line-height: 2rem;
	font-size: 0.64rem;
	color:#fff;
	position: fixed;
	bottom: 0;
	z-index:1000;
}
.img_btn span{
	float:left;
	width:50%;
	text-align: center;
}



Logo

前往低代码交流专区

更多推荐