基于cropper和sweetalert的简单图片/头像裁剪上传

基本功能

前端基本样式:

 

进行图片裁剪及上传:

 

点击上传后,js会将截取到的数据转为图片数据利用ajax发送给后台进行存储。存储成功后,刷新前端页面,头像改变。

 

 

上传成功后:自动刷新网页,更改头像

 

 基本工具

cropper是一个功能强大的jq插件,在指定图片img上添加裁剪框,并根据指定事件对图片按照裁剪框的大小进行裁剪。

crepper还可以对定义图片翻转、放大、移动以及输出裁剪框位置的很多功能,由于此处只是用于头像上传,所以只使用了基本功能。

cropper使用时需要用到jq2.0以上,所以加载cropper之前,一定要先加载jq,不然会报错。

sweetalert是一个界面优美使用简单、完全基于jq的一个模态框插件。由于自己在练习中使用sweetalert作为弹出框窗口,所以此处就没有自己写模态框也没有利用bootstrap的模态框。

后端是使用django进行处理。

基本代码

 

html:为了方便,使用了bootstrap样式。

加载库:

 <link rel="stylesheet" href="dist/css/bootstrap.min.css">
 <script src="dist/jquery.min.js"></script>
 <script src="js/sweetalert.min.js"></script>
 <script src="js/cropper.min.js"></script>
 <link rel="stylesheet" href="css/cropper.min.css">

 

    <div class="row">
        <div class=" col-sm-offset-1 col-sm-2 outter">
            {% csrf_token %}
            <div class="thumbnail ">
                <img id="img_thumbnail" src="/media/{{ user.thumbnail }}" alt="头像">
                <div class="btn-wrapper">
                <label class="btn btn-info btn-block btn-sm" id="up-btn">上传头像
                    <input id="up_thumbnail" type="file" style="display: none">
                </label>
            </div>
            </div>
        </div>
    </div>

 

 上传头像的input标签是隐藏在label中的。

css样式:

.row{
  .outter{
    .thumbnail{
      padding: 0;
      border: none;
      background-color: inherit;
      #img_thumbnail{
        width: 100%;
        object-fit: cover;
      }
      .btn-wrapper{
        margin-top: 5px;
      }
    }
  }
}

 

 

用的是sass语法,可以转换为css。

这里对图片显示用到了object-fit属性。因为前台显示图片的头像框大小是固定的,有时候上传的头像太小,这个属性可以将该图片填充满头像框。

js代码:

//将base64转换为文件,截取图片后会用到
function dataURLtoFile(dataurl, filename) {
    var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
        bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
    while (n--) {
        u8arr[n] = bstr.charCodeAt(n);
    }
    return new File([u8arr], filename, {type: mime});
}

$(function () {
    var up_thumbnail = $('#up_thumbnail');  //获取上传文件的input对象

    //选中文件后,触发change事件:
    up_thumbnail.change(function () {
        var file = this.files[0];  //获取图片对象

        //读取文件对象,弹出模态框,对图片进行预览
        filereader = new FileReader();
        filereader.readAsDataURL(file);
        filereader.onload = function () {
            //弹出模态框,模态框的内容content是一个img标签,classname是source-img,这个标签cropper要用到
            swal({
                content: {
                    element: 'img',
                    attributes: {
                        src: this.result,//此处的this.result就是读取的文件数据,放至img标签,进行预览
                        width: 400,
                        className: 'source-img'
                    }
                },
                buttons: {
                    cancel: { //取消按钮,点击后为null
                        text: '取消',
                        closeModal: true,
                        visible: true,
                    },
                    confirm: {   //确认按钮,点击后会返回true
                        text: '上传',
                        closeModal: false,
                        className: 'cut-btn',
                    }
                },
            }).then((value) => {  //点击按钮后,会将按钮的值传递给value,根据value进行下一步动作
                if (value) {  //如果value为真
                    if ($(".source-img").attr("src") == null) {  //图像框中没有图像,弹出error模态框,1秒后自动关闭
                        swal({
                            icon: 'error',
                            title: '没有图片上传',
                            timer: 1000
                        });
                    } else {  //图像框中有图像
                        var cas = $('.source-img').cropper('getCroppedCanvas');// 获取被裁剪后的canvas
                        var base64 = cas.toDataURL('image/jpeg'); // 转换为base64
                        var picture = dataURLtoFile(base64, file.name);//转换为图片对象

                        //使用ajax对图片文件进行传递
                        // 注意:这里的xfz_ajax是我自己写的对一个小封装,实际上就是自动将csrf_token的值加载到header,直接使用jq的ajax也可以实现。只不过多个步骤而已。
                        var formdata = new FormData();
                        formdata.append('thumbnail', picture); //前面为主键名,后面为文件对象
                        //使用jq的ajax时,post请求一定要记着带上csrf_token的值。
                        xfz_ajax.post({
                            'url': '/cms/upto_thumbnail/',
                            'data': formdata,
                            'processData': false,  //使用当前的数据,不用序列化
                            'contentType': false,//
                            'success': function (result) {
                                if (result.code === 200) {  //这个后台返回的code信息是我自定义的,上传成功会返回一个resul字典,其中一个key为code,成功值为200
                                    swal({   //上传成功,显示success模态框。其显示的信息为返回的信息。1.5秒后自动关闭模态框,并自动刷新网页
                                        title: result.message,
                                        icon: 'success',
                                        timer: 1500
                                    }).then(() => {
                                        window.location.reload()
                                    })
                                } else {
                                    swal({  //上传失败,弹出失败模态框
                                        title: result.message,
                                        icon: 'error',
                                        timer: 1500
                                    })
                                }
                            }
                        })

                    }

                }
            });

            //在生成模态框之后(只有生成了模态框,才有cropper需要的img标签)时候对cropper进行初始化。
            $('.source-img').cropper({
                aspectRatio: 1,// 默认比例
                preview: '#previewImg',// 预览视图,可以不要,如果想要预览,可以将一个img标签的id放进来
                guides: true, // 裁剪框的虚线(九宫格)
                autoCropArea: 0.8, // 0-1之间的数值,定义自动剪裁区域的大小,默认0.8
                movable: false, // 是否允许移动图片
                dragCrop: true, // 是否允许移除当前的剪裁框,并通过拖动来新建一个剪裁框区域
                movable: true, // 是否允许移动剪裁框
                resizable: true, // 是否允许改变裁剪框的
                zoomable: false, // 是否允许缩放图片大小
                mouseWheelZoom: false, // 是否允许通过鼠标滚轮来缩放图片
                touchDragZoom: true, // 是否允许通过触摸移动来缩放图片
                rotatable: false, // 是否允许旋转图片
                crop: function (e) {
                }
            });
        };
    });
});

 

 

 

 注意,ajax传递数据由于是用的一个ajax的小封装,省略了csrf_token的过程,使用时传递数据一定要携带csrf_token值。

 

 

以上前端代码就已经全部完成了,后端代码我使用的是django,直接利用model获取文件。

@require_POST
@login_required(login_url='news:news_index')
def upto_thumbnail(request):
    file = request.FILES.get('thumbnail')
    request.user.thumbnail = file
    request.user.save()
    return result.success(message='上传成功!')

 

一个简单实用的头像裁剪上传功能就实现了。

 

 

 

 

 

 

转载于:https://www.cnblogs.com/ohahastudy/p/11179354.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要实现Vue图片裁剪上传,可以使用vue-cropper组件。以下是一个简单的实现过程: 1. 首先,在Vue项目中安装vue-cropper组件。可以使用npm或yarn来安装,命令如下: ``` npm install vue-cropper ``` 2. 在需要使用图片裁剪上传的组件中,引入vue-cropper组件。可以在组件的template中添加以下代码: ```html <template> <div> <vue-cropper ref="cropper" :src="imageSrc" :guides="true" :view-mode="1" :auto-crop-area="0.8" ></vue-cropper> <button @click="cropImage">裁剪上传</button> </div> </template> ``` 3. 在组件的script部分,添加必要的代码。首先,引入vue-cropper组件: ```javascript import VueCropper from 'vue-cropper' ``` 然后,在components中注册vue-cropper组件: ```javascript components: { VueCropper }, ``` 接下来,定义data中的imageSrc属性,用于展示需要裁剪图片: ```javascript data() { return { imageSrc: '图片路径' } }, ``` 4. 实现裁剪上传功能。在methods中,定义cropImage方法: ```javascript methods: { cropImage() { const cropper = this.$refs.cropper const imageData = cropper.getCroppedCanvas().toDataURL('image/jpeg') // 将imageData发送到后端进行上传处理 // ... } }, ``` 在cropImage方法中,通过this.$refs.cropper获取vue-cropper组件实例,并使用getCroppedCanvas方法获取裁剪后的图片数据。最后,将图片数据发送到后端进行上传处理。 这样,就实现了Vue图片裁剪上传的功能。你可以根据具体的需求,自定义vue-cropper组件的属性和方法,来实现更多的功能。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值