Create appropriate thumbnails

parent bc34681e
...@@ -11,10 +11,10 @@ ...@@ -11,10 +11,10 @@
<ul class="gallery-photos row"> <ul class="gallery-photos row">
{% for photo in album.photos %} {% for photo in album.photos %}
<li class="post gallery-photo span3 has-overlay {% if forloop.counter0|divisibleby:4 %}first-child{% endif %}"> <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="post-inner">
<span class="inner-img"> <span class="inner-img">
<img src="{% thumbnail photo '220x200' %}" alt="" /> <img src="{% thumbnail photo '220x220' %}" alt="" />
</span> </span>
<span class="post-overlay"> <span class="post-overlay">
</span> </span>
......
...@@ -33,7 +33,7 @@ urlpatterns = [ ...@@ -33,7 +33,7 @@ urlpatterns = [
url(r'^photos/', include('photos.urls', namespace='photos')), url(r'^photos/', include('photos.urls', namespace='photos')),
])), ])),
url(r'^contact$', TemplateView.as_view(template_name='singlepages/contact.html'), name='contact'), 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 # Default login helpers
url(r'^', include('django.contrib.auth.urls')), url(r'^', include('django.contrib.auth.urls')),
url(r'^i18n/', include('django.conf.urls.i18n')), url(r'^i18n/', include('django.conf.urls.i18n')),
......
...@@ -2,33 +2,40 @@ from django import template ...@@ -2,33 +2,40 @@ from django import template
from django.conf import settings from django.conf import settings
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from PIL import Image, ImageOps
import os import os
import shutil
register = template.Library() register = template.Library()
@register.simple_tag @register.simple_tag
def thumbnail(path, size, fit=False): def thumbnail(path, size, fit=True):
size_fit = '{}_{}'.format(size, int(fit))
parts = path.split('/') parts = path.split('/')
# If we're dealing with an image in media/public/.. # If we're dealing with an image in media/public/..
if parts[0] == 'public': if parts[0] == 'public':
# We actually want it to end up in media/public/thumbnails/.. # We actually want it to end up in media/public/thumbnails/..
# since those files can be accessed without passing through a view. # 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: else:
# Otherwise simply place it in media/thumbnails. # 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_thumbpath = os.path.join(settings.MEDIA_ROOT, thumbpath)
full_path = os.path.join(settings.MEDIA_ROOT, path) full_path = os.path.join(settings.MEDIA_ROOT, path)
os.makedirs(os.path.dirname(full_thumbpath), exist_ok=True) os.makedirs(os.path.dirname(full_thumbpath), exist_ok=True)
# TODO actually create a thumbnail instead of copying image = Image.open(full_path)
shutil.copyfile(full_path, full_thumbpath) 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': if parts[0] == 'public':
return '/'.join([settings.MEDIA_URL, thumbpath]) return '/'.join([settings.MEDIA_URL, thumbpath])
else: else:
return reverse('private-thumbnails', args=[path]) return reverse('private-thumbnails', args=[size_fit, path])
...@@ -8,8 +8,9 @@ from .snippets import sanitize_path ...@@ -8,8 +8,9 @@ from .snippets import sanitize_path
@login_required @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? # 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' 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) 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