django + cropper 实现头像预览裁剪上传

思路:

使用cropper这个前端插件,对图片进行裁剪,cropper生成的截图,是一串base64的编码,再将其转为blob格式,传到后端,进行存储。简单的说就是前端裁剪好的图片,传到后端,而不是将裁减的数据值传到后端,在后端进行裁剪.


cropper的api:

https://github.com/fengyuanchen/cropper


cropper的简单使用:

html

<div>
  <img id="image" src="picture.jpg">
</div>

css

img {
  max-width: 100%; /*必填*/
}

js

var $image = $('#image');

$image.cropper({
  aspectRatio: 16 / 9,
  crop: function(event) {
    console.log(event.detail.x);
    console.log(event.detail.y);
    console.log(event.detail.width);
    console.log(event.detail.height);
    console.log(event.detail.rotate);
    console.log(event.detail.scaleX);
    console.log(event.detail.scaleY);
  }
});

//实例化
var cropper = $image.data('cropper');

使用cropper进行图片的裁剪

导入:
  <script src="{{STATIC_URL}}js/jquery.js"></script>
  <link  rel="stylesheet" type="text/css" href="{{STATIC_URL}}css/cropper.css" />
    <script src="{{STATIC_URL}}js/cropper.js" type="text/javascript" ></script>
css:
  body {
            font-size: 16px;
            font-family:"Microsoft YaHei",Arial, Helvetica, sans-serif
        }
        *,
        *:before,
        *:after {
            -webkit-box-sizing: border-box;
               -moz-box-sizing: border-box;
                -ms-box-sizing: border-box;
                    box-sizing: border-box;
        }

        .crop-picker-wrap {
            position: relative;
            width: 100px;
            height: 30px;
            overflow: hidden;
        }
        .crop-picker {
            width: 100%;
            height: 100%;
            line-height: 1;

            -webkit-appearance: none;
            margin: 0;
            border: none;
            border-radius: 5px;
            padding: 9px 0;
            background-color: #1ab2ff;

            color: #fff;            
            cursor: pointer;
        }
        .crop-picker-file {
            position: absolute;
            top: 0;
            right: 0;
            height: 100%;
            opacity: 0;
            cursor: pointer;
            filter: alpha(opacity=0);
        }

        .crop-save,
        .crop-cancel {
            display: inline-block;
            vertical-align: middle;

            width: 150px;
            height: 50px;
            line-height: 50px;

            -webkit-appearance: none;
            margin: 0 5px;
            border: none;
            border-radius: 5px;
            background-color: #1ab2ff;

            color: #fff;
            cursor: pointer;
        }

/* Apply these styles only when #preview-pane has
   been placed within the Jcrop widget */
.jcrop-holder #preview-pane {
  display: block;
  position: absolute;
  z-index: 2000;
  top: 10px;
  right: -280px;
  padding: 6px;
  border: 1px rgba(0,0,0,.4) solid;
  background-color: white;

  -webkit-border-radius: 6px;
  -moz-border-radius: 6px;
  border-radius: 6px;

  -webkit-box-shadow: 1px 1px 5px 2px rgba(0, 0, 0, 0.2);
  -moz-box-shadow: 1px 1px 5px 2px rgba(0, 0, 0, 0.2);
  box-shadow: 1px 1px 5px 2px rgba(0, 0, 0, 0.2);
}

/* The Javascript code will set the aspect ratio of the crop
   area based on the size of the thumbnail preview,
   specified here */
#preview-pane {
 float:right;
 }

#preview-pane .preview-container {
  overflow: hidden;
  border-style: groove;
  background-color: black;
  width: 160px;
  height: 160px;
}

#target {
    max-width: 100%; /* This rule is very important, please do not ignore this! */
}

.cut-container{
        width: 300px;
        height: 300px;
        margin:20px 30px;
        border:dashed #cacaca 1px;
}

#preview{
   max-width: 300px;
   max-height:300px;
}

#cropper-line{
      border-color:black;
}
   <div class="crop-picker-wrap">
      <button class="crop-picker" id='select' type="button">选择图片</button>
     <input type="file" class="crop-picker-file" id="inputImage" name="file" accept=".jpg,.jpeg,.png,.gif,.bmp,.tiff">>
        </div>
    //预览
  <div id="preview">
             {% if thumb_pic %}
             <img src="{{MEDIA_URL}}{{thumb_pic}}" id="target" />   
             {% else%}
             <img src="" id="target" /> 
             {% endif %}    
               <span>滚动放大或缩小</span> 
          </div>
            // 显示裁剪的效果图
          <div id="preview-pane">
            <div class="preview-container">
                 <img src="" id="cut_thumb"/>
            </div>
            <span>160*160</span>
          </div>

           <div class="crop-operate">
                <button class="crop-save" type='submit' id='save'>保存</button>
                <button class="crop-cancel" type="button" id='cancel'>取消</button>
            </div>

效果如下:

使用滚轮进行图片放大缩小,宽高是360*360
这里写图片描述

js:
var $image = $('#target');  
        $('[type=file]').change(function(e) {      
            var file = e.target.files[0]
            if(file.size>= 2*1024*1024){
                  layer.alert('您上传的头像大于2M,请重新上传', {
                      title:'提示',
                      icon: 0,
                      skin:'layui-layer-lan', //该皮肤由layer.seaning.com友情扩展。关于皮肤的扩展规则,去这里查阅
                    });
                }
            else{
                    var reader = new FileReader();
                    reader.readAsDataURL(file); 
                    reader.onload=function(e){
                    $image.attr("src",e.target.result)
                     $image.cropper('reset', true).cropper('replace',e.target.result);
                    }
                    if(($('#target').attr('src').length) != 0){
                         $('#preview').show()
                         $('#preview-pane').show()
                         $('.crop-operate').show()
                    } 
                }
          })
            $image.cropper({
                        dragMode: 'move',
                        viewMode:3,
                        aspectRatio:1,//1 / 1,  //图片比例,1:1
                        minCropBoxWidth:300,
                        minCropBoxHeight:300,
                        minContainerWidth:300,
                        minContainerHeight:300,
                        restore: false,
                        guides: false,
                        center: false,
                        highlight: false,
                        cropBoxMovable: false,
                        cropBoxResizable: false,
                        toggleDragModeOnDblclick: false,
                        modal:false,
                        responsive:false,
                        preview:'.preview-container',
                        background:false,     
                     });

 $('#thumb_upload').submit(function(){
      event.preventDefault();  
      // 获取裁图后图片的base64
     var $imgData=$image.cropper('getCroppedCanvas')
      var dataurl = $imgData.toDataURL('image/jpeg');
     // 将base64 转为 blob格式
      var b64 = dataurl.split(',')[1];
     var binary = atob(b64);
     var array = [];
     for (var i = 0; i < binary.length; i++) {
         array.push(binary.charCodeAt(i));
     }
     var blob =  new Blob([new Uint8Array(array)], {type: 'image/jpeg'})
     // 使用FormData()进行ajax请求,上传图片
     var formData = new FormData()
     // 图片名字
     var img_name = new Date().getTime()+'.jpg';
     formData.append('csrfmiddlewaretoken','{{ csrf_token }}')
     formData.append('uploadFile',blob,img_name)
     var data = formData
      $.ajax({
           url: "/上传地址/",
           type: "post",
           dataType: "json",
           data:data,
           processData: false,
           contentType:false,
           success:function(result){
               if(result['state']==0){
                    layer.close(layer.index);  
                    window.parent.location.reload();
               }
               if(result['state']==1){
                     layer.alert('上传失败,请联系客服', {
                          title:'提示',
                          icon: 0,
                          skin: 'layui-layer-lan'//该皮肤由layer.seaning.com友情扩展。关于皮肤的扩展规则,去这里查阅
                        },
                          function (){
                             window.parent.location.reload()
                        }
                    );      
               }
           }
      });
  });

  $('#cancel').click(function(){
      event.preventDefault();
      var index = parent.layer.getFrameIndex(window.name);  
      parent.layer.close(index);  
  })

</script>   

django后台:

    def post(self,request):
        try:
            id =request.user.id
            #  获取数据库
            user = 用户.objects.get(id=id)
            #  上传的图片
            thumb_file = request.FILES['uploadFile']
            user.picture = thumb_file
            user.save()
            to_json_response = {
                        'state':0
                        }
        except Exception as e:
            print(e)
            to_json_response={
                    'state':1
                }
        return HttpResponse(json.dumps(to_json_response), content_type='application/json')

猜你喜欢

转载自blog.csdn.net/qq_21570029/article/details/79972138