Train of thought:
Using the front-end plug-in of clipper, the pictures are cropped. The screenshot generated by clipper is a series of base64 codes, and then it is converted to blob format, which is transmitted to the back-end for storage. In short, it means that the front-end cut pictures are sent to the back-end, rather than the cut data values are sent to the back-end for cutting
Clipper api:
https://github.com/fengyuanchen/cropper
Simple use of clipper:
html
<div>
<img id="image" src="picture.jpg">
</div>
css
img {
max-width: 100%; /*Must fill*/
}
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);
}
});
//instantiation
var cropper = $image.data('cropper');
Using clipper to cut pictures
Import:
<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">Select pictures</button>
<input type="file" class="crop-picker-file" id="inputImage" name="file" accept=".jpg,.jpeg,.png,.gif,.bmp,.tiff">>
</div>
//preview
<div id="preview">
{% if thumb_pic %}
<img src="{{MEDIA_URL}}{{thumb_pic}}" id="target" />
{% else%}
<img src="" id="target" />
{% endif %}
<span>Scroll to zoom in or out</span>
</div>
// Show cropped renderings
<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'>Preservation</button>
<button class="crop-cancel" type="button" id='cancel'>cancel</button>
</div>
The effect is as follows:
Use the scroll wheel to zoom in and out the picture. The width and height are 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('Your uploaded picture is more than 2 M,Please upload again', {
title:'Tips',
icon: 0,
skin:'layui-layer-lan', //The skin is expanded by layer.mining.com. For skin extension rules, go here
});
}
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, / / picture scale, 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();
// Get base64 of cut image
var $imgData=$image.cropper('getCroppedCanvas')
var dataurl = $imgData.toDataURL('image/jpeg');
// Convert base64 to blob format
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'})
// Using FormData() to make ajax request and upload pictures
var formData = new FormData()
// Picture name
var img_name = new Date().getTime()+'.jpg';
formData.append('csrfmiddlewaretoken','{{ csrf_token }}')
formData.append('uploadFile',blob,img_name)
var data = formData
$.ajax({
url: "/Upload address/",
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('Upload failure,Please contact customer service', {
title:'Tips',
icon: 0,
skin: 'layui-layer-lan'//The skin is expanded by layer.mining.com. For skin extension rules, go here
},
function (){
window.parent.location.reload()
}
);
}
}
});
});
$('#cancel').click(function(){
event.preventDefault();
var index = parent.layer.getFrameIndex(window.name);
parent.layer.close(index);
})
</script>
django background:
def post(self,request):
try:
id =request.user.id
# Get database
user = user.objects.get(id=id)
# Uploaded pictures
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')