Create appropriate thumbnails

parent bc34681e
......@@ -11,10 +11,10 @@
<ul class="gallery-photos row">
{% for photo in album.photos %}
<li class="post gallery-photo span3 has-overlay {% if forloop.counter0|divisibleby:4 %}first-child{% endif %}">
<a class="gallery-box" rel="gallery" data-download="{% url 'photos:download' photo %}" href="{% thumbnail photo '1024x768' fit=True %}">
<a class="gallery-box" rel="gallery" data-download="{% url 'photos:download' photo %}" href="{% thumbnail photo '1024x768' fit=False %}">
<span class="post-inner">
<span class="inner-img">
<img src="{% thumbnail photo '220x200' %}" alt="" />
<img src="{% thumbnail photo '220x220' %}" alt="" />
</span>
<span class="post-overlay">
</span>
......
......@@ -33,7 +33,7 @@ urlpatterns = [
url(r'^photos/', include('photos.urls', namespace='photos')),
])),
url(r'^contact$', TemplateView.as_view(template_name='singlepages/contact.html'), name='contact'),
url(r'^private-thumbnails/(?P<path>.*)', private_thumbnails, name='private-thumbnails'),
url(r'^private-thumbnails/(?P<size_fit>\d+x\d+_[01])/(?P<path>.*)', private_thumbnails, name='private-thumbnails'),
# Default login helpers
url(r'^', include('django.contrib.auth.urls')),
url(r'^i18n/', include('django.conf.urls.i18n')),
......
......@@ -2,33 +2,40 @@ from django import template
from django.conf import settings
from django.core.urlresolvers import reverse
from PIL import Image, ImageOps
import os
import shutil
register = template.Library()
@register.simple_tag
def thumbnail(path, size, fit=False):
def thumbnail(path, size, fit=True):
size_fit = '{}_{}'.format(size, int(fit))
parts = path.split('/')
# If we're dealing with an image in media/public/..
if parts[0] == 'public':
# We actually want it to end up in media/public/thumbnails/..
# since those files can be accessed without passing through a view.
thumbpath = os.path.join(parts[0], 'thumbnails', *parts[1:])
thumbpath = os.path.join(parts[0], 'thumbnails', size_fit, *parts[1:])
else:
# Otherwise simply place it in media/thumbnails.
thumbpath = os.path.join('thumbnails', path)
thumbpath = os.path.join('thumbnails', size_fit, path)
full_thumbpath = os.path.join(settings.MEDIA_ROOT, thumbpath)
full_path = os.path.join(settings.MEDIA_ROOT, path)
os.makedirs(os.path.dirname(full_thumbpath), exist_ok=True)
# TODO actually create a thumbnail instead of copying
shutil.copyfile(full_path, full_thumbpath)
image = Image.open(full_path)
size = tuple(int(dim) for dim in size.split('x'))
if not fit:
ratio = min([a / b for a, b in zip(size, image.size)])
size = tuple(int(ratio * x) for x in image.size)
thumb = ImageOps.fit(image, size, Image.ANTIALIAS)
thumb.save(full_thumbpath)
if parts[0] == 'public':
return '/'.join([settings.MEDIA_URL, thumbpath])
else:
return reverse('private-thumbnails', args=[path])
return reverse('private-thumbnails', args=[size_fit, path])
......@@ -8,8 +8,9 @@ from .snippets import sanitize_path
@login_required
def private_thumbnails(request, path):
def private_thumbnails(request, size_fit, path):
# TODO do a bit more error handling if the path does not exist?
# 'path' is supplied as a URL parameter, so treat with care!
path = os.path.join(settings.MEDIA_ROOT, 'thumbnails', sanitize_path(path))
path = sanitize_path(path)
path = os.path.join(settings.MEDIA_ROOT, 'thumbnails', size_fit, path)
return sendfile(request, path)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment