Better handle rotations

This commit is contained in:
Skia 2016-11-20 13:39:04 +01:00
parent 869634d6e1
commit 815ef03860
6 changed files with 55 additions and 10 deletions

View File

@ -12,7 +12,7 @@
{% 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%">
<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>
</div>
{% endfor %}

View File

@ -1,7 +1,7 @@
# Image utils
from io import BytesIO
from PIL import Image
from PIL import Image, ExifTags
# from exceptions import IOError
import PIL
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)
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

View File

@ -1950,7 +1950,7 @@ msgstr "Erreur de création du dossier %(folder_name)s : %(msg)s"
#: sas/views.py:41
#, python-format
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
msgid "Choose file"

View File

@ -30,6 +30,19 @@ class Picture(SithFile):
def get_download_thumb_url(self):
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):
return self.parent.children.exclude(is_moderated=False, asked_for_removal=True).filter(id__gt=self.id).order_by('id').first()

View File

@ -34,8 +34,12 @@
{% block content %}
{{ print_path(picture.parent) }} {{ picture.get_display_name() }}
<h3>{{ picture.get_display_name() }}</h3>
<div style="display: inline-block; width: 89%; background: #333;" id="pict">
<img src="{{ picture.get_download_compressed_url() }}" alt="{{ picture.get_display_name() }}" style="width: 90%; display: block; margin: auto"/>
<div style="display: inline-block; width: 89%; background: #333; border: solid #333 2px;" id="pict">
{% 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 style="display: inline-block; width: 10%; vertical-align: top;">
<div>
@ -77,7 +81,9 @@
<a href="{{ picture.get_download_url() }}">{% trans %}HD version{% endtrans %}</a>
</p>
<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>
</div>
{% endblock %}

View File

@ -10,12 +10,16 @@ from django.core.exceptions import PermissionDenied
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.forms import SelectUser, LoginForm, SelectDate, SelectDateTime
from core.views.files import send_file
from core.models import SithFile, User
from sas.models import Picture, Album, PeoplePictureRelation
from core.utils import resize_image, exif_auto_rotate
class SASForm(forms.Form):
album_name = forms.CharField(label=_("Add a new album"), max_length=30, required=False)
@ -23,9 +27,6 @@ class SASForm(forms.Form):
required=False)
def process(self, parent, owner, files, automodere=False):
from core.utils import resize_image
from io import BytesIO
from PIL import Image
try:
if self.cleaned_data['album_name'] != "":
album = Album(parent=parent, name=self.cleaned_data['album_name'], owner=owner, is_moderated=automodere)
@ -40,14 +41,19 @@ class SASForm(forms.Form):
try:
new_file.clean()
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])
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.name = new_file.name
new_file.compressed = compressed
new_file.compressed.name = new_file.name
new_file.save()
print(new_file.compressed)
except Exception as 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):
self.object = self.get_object()
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():
try:
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):
kwargs = super(PictureView, self).get_context_data(**kwargs)
kwargs['form'] = self.form
im = Image.open(BytesIO(self.object.file.read()))
(w, h) = im.size
kwargs['is_vertical'] = (w / h) < 1
return kwargs
def get_success_url(self):