mirror of
https://gitlab.crans.org/bde/nk20
synced 2024-11-26 18:37:12 +00:00
add support for cropping image. WIP.
This commit is contained in:
parent
13055c393a
commit
08b97e722b
@ -16,6 +16,7 @@ from django.core.exceptions import ValidationError
|
|||||||
from django_tables2.views import SingleTableView
|
from django_tables2.views import SingleTableView
|
||||||
from rest_framework.authtoken.models import Token
|
from rest_framework.authtoken.models import Token
|
||||||
from dal import autocomplete
|
from dal import autocomplete
|
||||||
|
from PIL import Image
|
||||||
|
|
||||||
from note.models import Alias, NoteUser
|
from note.models import Alias, NoteUser
|
||||||
from note.models.transactions import Transaction
|
from note.models.transactions import Transaction
|
||||||
@ -229,8 +230,16 @@ class ProfilePictureUpdateView(LoginRequiredMixin, FormMixin, DetailView):
|
|||||||
return self.form_invalid(form)
|
return self.form_invalid(form)
|
||||||
|
|
||||||
def form_valid(self,form):
|
def form_valid(self,form):
|
||||||
print(form)
|
image_file_field = form.cleaned_data['image']
|
||||||
self.object.note.display_image = form.cleaned_data.get("image","pic/default.png")
|
x = form.cleaned_data['x']
|
||||||
|
y = form.cleaned_data['y']
|
||||||
|
w = form.cleaned_data['width']
|
||||||
|
h = form.cleaned_data['height']
|
||||||
|
with Image.open(image_file_field.name) as image:
|
||||||
|
image = image.crop((x, y, w+x, h+y))
|
||||||
|
image.thumbnail((256, 256), Image.ANTIALIAS)
|
||||||
|
image.save(image_file_field.name,format=image.format)
|
||||||
|
self.object.note.display_image = image_file_field
|
||||||
self.object.note.save()
|
self.object.note.save()
|
||||||
return super().form_valid(form)
|
return super().form_valid(form)
|
||||||
|
|
||||||
|
@ -3,8 +3,11 @@
|
|||||||
|
|
||||||
from dal import autocomplete
|
from dal import autocomplete
|
||||||
from django import forms
|
from django import forms
|
||||||
|
from django.conf import settings
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
from crispy_forms.helper import FormHelper
|
from crispy_forms.helper import FormHelper
|
||||||
from crispy_forms.bootstrap import Div
|
from crispy_forms.bootstrap import Div
|
||||||
from crispy_forms.layout import Layout, HTML
|
from crispy_forms.layout import Layout, HTML
|
||||||
@ -27,8 +30,12 @@ class ImageForm(forms.Form):
|
|||||||
image = forms.ImageField(required = False,
|
image = forms.ImageField(required = False,
|
||||||
label=_('select an image'),
|
label=_('select an image'),
|
||||||
help_text=_('Maximal size: 2MB'))
|
help_text=_('Maximal size: 2MB'))
|
||||||
|
x = forms.FloatField(widget=forms.HiddenInput())
|
||||||
|
y = forms.FloatField(widget=forms.HiddenInput())
|
||||||
|
width = forms.FloatField(widget=forms.HiddenInput())
|
||||||
|
height = forms.FloatField(widget=forms.HiddenInput())
|
||||||
|
|
||||||
|
|
||||||
class TransactionTemplateForm(forms.ModelForm):
|
class TransactionTemplateForm(forms.ModelForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = TransactionTemplate
|
model = TransactionTemplate
|
||||||
|
@ -191,3 +191,7 @@ ALIAS_VALIDATOR_REGEX = r''
|
|||||||
|
|
||||||
MEDIA_ROOT=os.path.join(BASE_DIR,"media")
|
MEDIA_ROOT=os.path.join(BASE_DIR,"media")
|
||||||
MEDIA_URL='/media/'
|
MEDIA_URL='/media/'
|
||||||
|
|
||||||
|
# Profile Picture Settings
|
||||||
|
PIC_WIDTH = 200
|
||||||
|
PIC_RATIO = 1
|
||||||
|
@ -26,3 +26,4 @@ urlpatterns = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
urlpatterns += static(settings.MEDIA_URL,document_root=settings.MEDIA_ROOT)
|
urlpatterns += static(settings.MEDIA_URL,document_root=settings.MEDIA_ROOT)
|
||||||
|
urlpatterns += static(settings.STATIC_URL,document_root=settings.STATIC_ROOT)
|
||||||
|
@ -2,62 +2,94 @@
|
|||||||
{% load i18n static pretty_money django_tables2 crispy_forms_tags %}
|
{% load i18n static pretty_money django_tables2 crispy_forms_tags %}
|
||||||
|
|
||||||
{% block profile_content %}
|
{% block profile_content %}
|
||||||
<div class="row">
|
<form method="post" enctype="multipart/form-data" id="formUpload">
|
||||||
<div class="col-sm-4 text-center">
|
{% csrf_token %}
|
||||||
<img class="img-thumbnail" alt="" src="{{user_object.note.display_image.url }}"/>
|
{{ form |crispy }}
|
||||||
<p class=""> {% trans "current image" %} </p>
|
</form>
|
||||||
</div>
|
<!-- MODAL TO CROP THE IMAGE -->
|
||||||
<div class="col-sm-4 justify-content-center">
|
<div class="modal fade" id="modalCrop">
|
||||||
<form class=" text-center form my-2" action="" enctype="multipart/form-data" method="post">
|
<div class="modal-dialog">
|
||||||
{% csrf_token %}
|
<div class="modal-content">
|
||||||
{{ form |crispy }}
|
<div class="modal-body">
|
||||||
<button class="btn btn-primary mx-2" type="submit">
|
<img src="" id="modal-image" style="max-width: 100%;">
|
||||||
{% trans "Change image" %}
|
</div>
|
||||||
</button>
|
<div class="modal-footer">
|
||||||
</form>
|
<div class="btn-group pull-left" role="group">
|
||||||
</div>
|
<button type="button" class="btn btn-default" id="js-zoom-in">
|
||||||
<div class="col-sm-4">
|
<span class="glyphicon glyphicon-zoom-in"></span>
|
||||||
<div id="image-holder"></div>
|
</button>
|
||||||
</div>
|
<button type="button" class="btn btn-default js-zoom-out">
|
||||||
|
<span class="glyphicon glyphicon-zoom-out"></span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<button type="button" class="btn btn-default" data-dismiss="modal">Nevermind</button>
|
||||||
|
<button type="button" class="btn btn-primary js-crop-and-upload">Crop and upload</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
{% block extracss %}
|
||||||
|
<link href="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.5.6/cropper.min.css" rel="stylesheet">
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
{% block extrajavascript%}
|
{% block extrajavascript%}
|
||||||
<script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.5.6/cropper.min.js"></script>
|
||||||
// https://codepedia.info/upload-image-using-jquery-ajax-asp-net-c-sharp/
|
<script src="https://cdn.jsdelivr.net/npm/jquery-cropper@1.0.1/dist/jquery-cropper.min.js"></script>
|
||||||
$("#id_image").on('change', function () {
|
<script>
|
||||||
|
$(function () {
|
||||||
//Get count of selected files
|
|
||||||
var countFiles = $(this)[0].files.length;
|
|
||||||
|
|
||||||
var imgPath = $(this)[0].value;
|
|
||||||
var extn = imgPath.substring(imgPath.lastIndexOf('.') + 1).toLowerCase();
|
|
||||||
var image_holder = $("#image-holder");
|
|
||||||
image_holder.empty();
|
|
||||||
|
|
||||||
if (extn == "gif" || extn == "png" || extn == "jpg" || extn == "jpeg") {
|
|
||||||
if (typeof (FileReader) != "undefined") {
|
|
||||||
|
|
||||||
//loop for each file selected for uploaded.
|
|
||||||
for (var i = 0; i < countFiles; i++) {
|
|
||||||
|
|
||||||
|
/* SCRIPT TO OPEN THE MODAL WITH THE PREVIEW */
|
||||||
|
$("#id_image").change(function (e) {
|
||||||
|
if (this.files && this.files[0]) {
|
||||||
var reader = new FileReader();
|
var reader = new FileReader();
|
||||||
reader.onload = function (e) {
|
reader.onload = function (e) {
|
||||||
$("<img />", {
|
$("#modal-image").attr("src", e.target.result);
|
||||||
"src": e.target.result,
|
$("#modalCrop").modal("show");
|
||||||
"class": "img-thumbnail"
|
|
||||||
}).appendTo(image_holder);
|
|
||||||
}
|
}
|
||||||
|
reader.readAsDataURL(this.files[0]);
|
||||||
image_holder.show();
|
|
||||||
reader.readAsDataURL($(this)[0].files[i]);
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
} else {
|
/* SCRIPTS TO HANDLE THE CROPPER BOX */
|
||||||
alert("{% trans 'This browser does not support FileReader.' %}");
|
var $image = $("#modal-image");
|
||||||
}
|
var cropBoxData;
|
||||||
} else {
|
var canvasData;
|
||||||
alert("{% trans 'Please select only images' %}");
|
$("#modalCrop").on("shown.bs.modal", function () {
|
||||||
}
|
$image.cropper({
|
||||||
});
|
viewMode: 1,
|
||||||
</script>
|
aspectRatio: 1/1,
|
||||||
|
minCropBoxWidth: 200,
|
||||||
|
minCropBoxHeight: 200,
|
||||||
|
ready: function () {
|
||||||
|
$image.cropper("setCanvasData", canvasData);
|
||||||
|
$image.cropper("setCropBoxData", cropBoxData);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}).on("hidden.bs.modal", function () {
|
||||||
|
cropBoxData = $image.cropper("getCropBoxData");
|
||||||
|
canvasData = $image.cropper("getCanvasData");
|
||||||
|
$image.cropper("destroy");
|
||||||
|
});
|
||||||
|
|
||||||
|
$(".js-zoom-in").click(function () {
|
||||||
|
$image.cropper("zoom", 0.1);
|
||||||
|
});
|
||||||
|
|
||||||
|
$(".js-zoom-out").click(function () {
|
||||||
|
$image.cropper("zoom", -0.1);
|
||||||
|
});
|
||||||
|
|
||||||
|
/* SCRIPT TO COLLECT THE DATA AND POST TO THE SERVER */
|
||||||
|
$(".js-crop-and-upload").click(function () {
|
||||||
|
var cropData = $image.cropper("getData");
|
||||||
|
$("#id_x").val(cropData["x"]);
|
||||||
|
$("#id_y").val(cropData["y"]);
|
||||||
|
$("#id_height").val(cropData["height"]);
|
||||||
|
$("#id_width").val(cropData["width"]);
|
||||||
|
$("#formUpload").submit();
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
Loading…
Reference in New Issue
Block a user