When writing a new blog, I encountered a process that requires users to upload custom pictures. After checking some information, I decided to use cropper and pillow to handle the upload of pictures that need to be cropped. The general idea is: the front end collects pictures uploaded by users and cropping by users. After receiving the picture in the background, it will be cut and saved according to the data, but I have not come up with a more reasonable way to cut the temporary file, only the simple implementation in the early stage is recorded here.
1.cropper
github: https://github.com/fengyuanchen/cropper
Here I introduced it according to the tutorial
cropper.min.css
cropper.min.js
But it will report an error, TypeError: image.cropper is not a function until I introduced this to solve the error problem, and they all depend on jquery
jquery-cropper.min.js
{#cropper编辑区域#} <div class="avatar-wrapper" id='avatar-wrapper'> <img src=""> </div> {#avatar preview area#} <div class="avatar-preview" style=" border-radius: 15%">
<img style="width: 96px; height: 96px;" src="">
</div> {#Upload button#} <a id="upload" class="btn btn-primary">上传头像</a> <label class="btn btn-primary" for="avatar-input">选择图片</label>
{#form#}
<form action="" method="post" id="avatar_form" enctype="multipart/form-data">
{%csrf_token%}
<input style="display:none" type="file" class="avatar-input" id="avatar-input" name="avatar_file" accept=".jpg,.jpeg,.png">
<input type="hidden" id="avatar_x" name="avatar_x">
<input type="hidden" id="avatar_y" name="avatar_y">
<input type="hidden" id="avatar_width" name="avatar_width">
<input type="hidden" id="avatar_height" name="avatar_height">
</form>
The main content of the template is these, mainly composed of editing area, preview area, upload button and hidden form. The preview area can display the original avatar or default avatar according to your own needs, and save the image and size data in the hidden form through js. Upload to the background in the form
Initialization of cropper:
var image = $ ('# avatar-wrapper img' ); image.cropper({ checkImageOrigin: true , // Check the image source dragMode: 'move', // The image can be moved restore: false , // The cropping area is not automatically restored after the form is resized zoomOnWheel: false , // It is not allowed to zoom by the mouse wheel zoomOnTouch: false , // don't allow zooming by touch aspectRatio: 1 / 1, // crop ratio autoCropArea: 0.5, // crop background transparency autoCropArea: 1, // auto crop ratio preview: ".avatar-preview", // preview area crop: function (e) { // Return image editing related data $('#avatar_x' ).val(e.detail.x); $( '#avatar_y' ).val(e.detail.y); $('#avatar_width').val(e.detail.width); $('#avatar_height').val(e.detail.height); }, });
Upload the image to cropper for cropping:
$("#avatar-input").change(function(){ var URL = window.URL || window.webkitURL; if(URL){ var files = this.files; if (files && files.length){ var file = files[0]; if (/^image\/\w+$/.test(file.type)) { var blobURL = URL.createObjectURL(file); image.cropper('reset').cropper('replace', blobURL); $('.avatar_crop .disabled').removeClass('disabled'); } else { alert( 'Please select a picture' ); } } } });
Upload to the background: (I use the jquery-form.js plugin, ordinary ajax methods are also available)
$('#upload').click(function () { if($('#avatar-wrapper img').attr('src')==''){ $( '#infoModal h4').html('Please select an image first' ) $('#infoModal').modal('show') return false;} var $form=$("#avatar_form") $form.ajaxSubmit(function (headpicaddress) { })
2.pillow
def user_my_info_headpic(request): #cut data to get top = int(float(request.POST[ ' avatar_y ' ])) buttom = top + int(float(request.POST['avatar_height'])) left = int(float(request.POST['avatar_x'])) right = left + int(float(request.POST['avatar_width'])) # 图片临时保存 with open(os.path.join(settings.BASE_DIR, "test1.jpg"), "wb") as f: for line in request.FILES['avatar_file']: f.write(line) #Open the picture im = Image.open(os.path.join(settings.BASE_DIR, " test1.jpg " ) ) #Crop the picture crop_im = im.crop((left, top, right, buttom)) #Save the picture crop_im. save(os.path.join(settings.BASE_DIR, " test2.jpg " )) return HttpResponse( " ok " )
This is my view method, the routing part is omitted, it is simply saved in a temporary location, I will sort out a more reasonable method and complete process later