mirror of
https://github.com/ae-utbm/sith.git
synced 2024-11-25 02:24:26 +00:00
Better handle rotations
This commit is contained in:
parent
869634d6e1
commit
815ef03860
@ -12,7 +12,7 @@
|
|||||||
{% for r in user.pictures.exclude(picture=None).filter(picture__parent=album) %}
|
{% for r in user.pictures.exclude(picture=None).filter(picture__parent=album) %}
|
||||||
<div style="display: inline-block; border: solid 1px black; width: 9%; margin: 0.1%">
|
<div style="display: inline-block; border: solid 1px black; width: 9%; margin: 0.1%">
|
||||||
<a href="{{ url("sas:picture", picture_id=r.picture.id) }}#pict">
|
<a href="{{ url("sas:picture", picture_id=r.picture.id) }}#pict">
|
||||||
<img src="{{ r.picture.as_picture.get_download_url() }}" alt="{{ r.picture.get_display_name() }}" style="max-width: 100%"/>
|
<img src="{{ r.picture.as_picture.get_download_thumb_url() }}" alt="{{ r.picture.get_display_name() }}" style="max-width: 100%"/>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# Image utils
|
# Image utils
|
||||||
|
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
from PIL import Image
|
from PIL import Image, ExifTags
|
||||||
# from exceptions import IOError
|
# from exceptions import IOError
|
||||||
import PIL
|
import PIL
|
||||||
from django.core.files.base import ContentFile
|
from django.core.files.base import ContentFile
|
||||||
@ -25,3 +25,16 @@ def resize_image(im, edge, format):
|
|||||||
im.save(fp=content, format=format.upper(), quality=90, optimize=True, progressive=True)
|
im.save(fp=content, format=format.upper(), quality=90, optimize=True, progressive=True)
|
||||||
return ContentFile(content.getvalue())
|
return ContentFile(content.getvalue())
|
||||||
|
|
||||||
|
def exif_auto_rotate(image):
|
||||||
|
for orientation in ExifTags.TAGS.keys() :
|
||||||
|
if ExifTags.TAGS[orientation]=='Orientation' : break
|
||||||
|
exif=dict(image._getexif().items())
|
||||||
|
|
||||||
|
if exif[orientation] == 3 :
|
||||||
|
image=image.rotate(180, expand=True)
|
||||||
|
elif exif[orientation] == 6 :
|
||||||
|
image=image.rotate(270, expand=True)
|
||||||
|
elif exif[orientation] == 8 :
|
||||||
|
image=image.rotate(90, expand=True)
|
||||||
|
|
||||||
|
return image
|
||||||
|
@ -1950,7 +1950,7 @@ msgstr "Erreur de création du dossier %(folder_name)s : %(msg)s"
|
|||||||
#: sas/views.py:41
|
#: sas/views.py:41
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Error uploading file %(file_name)s: %(msg)s"
|
msgid "Error uploading file %(file_name)s: %(msg)s"
|
||||||
msgstr "Erreur d'envoie du fichier %(file_name)s : %(msg)s"
|
msgstr "Erreur d'envoi du fichier %(file_name)s : %(msg)s"
|
||||||
|
|
||||||
#: core/views/forms.py:59 core/views/forms.py:62
|
#: core/views/forms.py:59 core/views/forms.py:62
|
||||||
msgid "Choose file"
|
msgid "Choose file"
|
||||||
|
@ -30,6 +30,19 @@ class Picture(SithFile):
|
|||||||
def get_download_thumb_url(self):
|
def get_download_thumb_url(self):
|
||||||
return reverse('sas:download_thumb', kwargs={'picture_id': self.id})
|
return reverse('sas:download_thumb', kwargs={'picture_id': self.id})
|
||||||
|
|
||||||
|
def rotate(self, degree):
|
||||||
|
from PIL import Image
|
||||||
|
from io import BytesIO
|
||||||
|
from django.core.files.base import ContentFile
|
||||||
|
for attr in ['file', 'compressed', 'thumbnail']:
|
||||||
|
if self.__getattribute__(attr):
|
||||||
|
im = Image.open(BytesIO(self.__getattribute__(attr).read()))
|
||||||
|
new_image = BytesIO()
|
||||||
|
im = im.rotate(degree, expand=True)
|
||||||
|
im.save(fp=new_image, format=self.mime_type.split('/')[-1].upper(), quality=90, optimize=True, progressive=True)
|
||||||
|
self.__getattribute__(attr).save(self.name, ContentFile(new_image.getvalue()))
|
||||||
|
self.save()
|
||||||
|
|
||||||
def get_next(self):
|
def get_next(self):
|
||||||
return self.parent.children.exclude(is_moderated=False, asked_for_removal=True).filter(id__gt=self.id).order_by('id').first()
|
return self.parent.children.exclude(is_moderated=False, asked_for_removal=True).filter(id__gt=self.id).order_by('id').first()
|
||||||
|
|
||||||
|
@ -34,8 +34,12 @@
|
|||||||
{% block content %}
|
{% block content %}
|
||||||
{{ print_path(picture.parent) }} {{ picture.get_display_name() }}
|
{{ print_path(picture.parent) }} {{ picture.get_display_name() }}
|
||||||
<h3>{{ picture.get_display_name() }}</h3>
|
<h3>{{ picture.get_display_name() }}</h3>
|
||||||
<div style="display: inline-block; width: 89%; background: #333;" id="pict">
|
<div style="display: inline-block; width: 89%; background: #333; border: solid #333 2px;" id="pict">
|
||||||
<img src="{{ picture.get_download_compressed_url() }}" alt="{{ picture.get_display_name() }}" style="width: 90%; display: block; margin: auto"/>
|
{% if is_vertical %}
|
||||||
|
<img src="{{ picture.get_download_compressed_url() }}" alt="{{ picture.get_display_name() }}" style="width: 60%; display: block; margin: auto"/>
|
||||||
|
{% else %}
|
||||||
|
<img src="{{ picture.get_download_compressed_url() }}" alt="{{ picture.get_display_name() }}" style="width: 100%; display: block; margin: auto"/>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
<div style="display: inline-block; width: 10%; vertical-align: top;">
|
<div style="display: inline-block; width: 10%; vertical-align: top;">
|
||||||
<div>
|
<div>
|
||||||
@ -77,7 +81,9 @@
|
|||||||
<a href="{{ picture.get_download_url() }}">{% trans %}HD version{% endtrans %}</a>
|
<a href="{{ picture.get_download_url() }}">{% trans %}HD version{% endtrans %}</a>
|
||||||
</p>
|
</p>
|
||||||
<p style="font-size: smaller;">
|
<p style="font-size: smaller;">
|
||||||
<a href="?ask_removal">{% trans %}Ask for removal{% endtrans %}</a>
|
<a href="?rotate_left">{% trans %}Rotate left{% endtrans %}</a><br>
|
||||||
|
<a href="?rotate_right">{% trans %}Rotate right{% endtrans %}</a><br>
|
||||||
|
<a href="?ask_removal">{% trans %}Ask for removal{% endtrans %}</a><br>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
21
sas/views.py
21
sas/views.py
@ -10,12 +10,16 @@ from django.core.exceptions import PermissionDenied
|
|||||||
|
|
||||||
from ajax_select import make_ajax_form, make_ajax_field
|
from ajax_select import make_ajax_form, make_ajax_field
|
||||||
|
|
||||||
|
from io import BytesIO
|
||||||
|
from PIL import Image
|
||||||
|
|
||||||
from core.views import CanViewMixin, CanEditMixin, CanEditPropMixin, CanCreateMixin, TabedViewMixin
|
from core.views import CanViewMixin, CanEditMixin, CanEditPropMixin, CanCreateMixin, TabedViewMixin
|
||||||
from core.views.forms import SelectUser, LoginForm, SelectDate, SelectDateTime
|
from core.views.forms import SelectUser, LoginForm, SelectDate, SelectDateTime
|
||||||
from core.views.files import send_file
|
from core.views.files import send_file
|
||||||
from core.models import SithFile, User
|
from core.models import SithFile, User
|
||||||
|
|
||||||
from sas.models import Picture, Album, PeoplePictureRelation
|
from sas.models import Picture, Album, PeoplePictureRelation
|
||||||
|
from core.utils import resize_image, exif_auto_rotate
|
||||||
|
|
||||||
class SASForm(forms.Form):
|
class SASForm(forms.Form):
|
||||||
album_name = forms.CharField(label=_("Add a new album"), max_length=30, required=False)
|
album_name = forms.CharField(label=_("Add a new album"), max_length=30, required=False)
|
||||||
@ -23,9 +27,6 @@ class SASForm(forms.Form):
|
|||||||
required=False)
|
required=False)
|
||||||
|
|
||||||
def process(self, parent, owner, files, automodere=False):
|
def process(self, parent, owner, files, automodere=False):
|
||||||
from core.utils import resize_image
|
|
||||||
from io import BytesIO
|
|
||||||
from PIL import Image
|
|
||||||
try:
|
try:
|
||||||
if self.cleaned_data['album_name'] != "":
|
if self.cleaned_data['album_name'] != "":
|
||||||
album = Album(parent=parent, name=self.cleaned_data['album_name'], owner=owner, is_moderated=automodere)
|
album = Album(parent=parent, name=self.cleaned_data['album_name'], owner=owner, is_moderated=automodere)
|
||||||
@ -40,14 +41,19 @@ class SASForm(forms.Form):
|
|||||||
try:
|
try:
|
||||||
new_file.clean()
|
new_file.clean()
|
||||||
im = Image.open(BytesIO(f.read()))
|
im = Image.open(BytesIO(f.read()))
|
||||||
|
try:
|
||||||
|
im = exif_auto_rotate(im)
|
||||||
|
except: pass
|
||||||
|
file = resize_image(im, max(im.size), f.content_type.split('/')[-1])
|
||||||
thumb = resize_image(im, 200, f.content_type.split('/')[-1])
|
thumb = resize_image(im, 200, f.content_type.split('/')[-1])
|
||||||
compressed = resize_image(im, 600, f.content_type.split('/')[-1])
|
compressed = resize_image(im, 600, f.content_type.split('/')[-1])
|
||||||
|
new_file.file = file
|
||||||
|
new_file.file.name = new_file.name
|
||||||
new_file.thumbnail = thumb
|
new_file.thumbnail = thumb
|
||||||
new_file.thumbnail.name = new_file.name
|
new_file.thumbnail.name = new_file.name
|
||||||
new_file.compressed = compressed
|
new_file.compressed = compressed
|
||||||
new_file.compressed.name = new_file.name
|
new_file.compressed.name = new_file.name
|
||||||
new_file.save()
|
new_file.save()
|
||||||
print(new_file.compressed)
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.add_error(None, _("Error uploading file %(file_name)s: %(msg)s") % {'file_name': f, 'msg': repr(e)})
|
self.add_error(None, _("Error uploading file %(file_name)s: %(msg)s") % {'file_name': f, 'msg': repr(e)})
|
||||||
|
|
||||||
@ -94,6 +100,10 @@ class PictureView(CanViewMixin, DetailView, FormMixin):
|
|||||||
def get(self, request, *args, **kwargs):
|
def get(self, request, *args, **kwargs):
|
||||||
self.object = self.get_object()
|
self.object = self.get_object()
|
||||||
self.form = self.get_form()
|
self.form = self.get_form()
|
||||||
|
if 'rotate_right' in request.GET.keys():
|
||||||
|
self.object.rotate(270)
|
||||||
|
if 'rotate_left' in request.GET.keys():
|
||||||
|
self.object.rotate(90)
|
||||||
if 'remove_user' in request.GET.keys():
|
if 'remove_user' in request.GET.keys():
|
||||||
try:
|
try:
|
||||||
user = User.objects.filter(id=int(request.GET['remove_user'])).first()
|
user = User.objects.filter(id=int(request.GET['remove_user'])).first()
|
||||||
@ -122,6 +132,9 @@ class PictureView(CanViewMixin, DetailView, FormMixin):
|
|||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
kwargs = super(PictureView, self).get_context_data(**kwargs)
|
kwargs = super(PictureView, self).get_context_data(**kwargs)
|
||||||
kwargs['form'] = self.form
|
kwargs['form'] = self.form
|
||||||
|
im = Image.open(BytesIO(self.object.file.read()))
|
||||||
|
(w, h) = im.size
|
||||||
|
kwargs['is_vertical'] = (w / h) < 1
|
||||||
return kwargs
|
return kwargs
|
||||||
|
|
||||||
def get_success_url(self):
|
def get_success_url(self):
|
||||||
|
Loading…
Reference in New Issue
Block a user