A Django image thumbnail filter

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
from django import template
from PIL import Image
from <APPNAME> import settings
import os

"""Thumbnail filter based on code from
http://batiste.dosimple.ch/blog/2007-05-13-1/. First hacked on
http://www.stereoplex.com/two-voices/a-django-image-thumbnail-filter
hacked further by Nido Media"""

register = template.Library()

THUMBNAILS = 'thumbnails'
SCALE_WIDTH = 'w'
SCALE_HEIGHT = 'h'

def scale(max_x, pair):
   """scales pair. Say pair is (x, y). The returned pair will be
   (max_x, ''y scaled by max_x / x'')"""
   x, y = pair
   new_y = max_x * y / x
   return (int(max_x), int(new_y))

@register.filter
def thumbnail(image, arg):
   """ Checks if a thumbnail image already exists. If not, one is
   created. The thumbnail will reside in the thumbnail folder
   relative to the original image path, and bears an indication of it's
   new size. This filter will return the URL of the thumbnail image.
   TODO: This filter may not be thread safe"""
   if not image:
       return ''

   original_image_path = settings.MEDIA_ROOT + image.__str__()
   original_image_url = image.url

   size = arg

   if image.width < image.height:
       mode = SCALE_HEIGHT
   else:
       mode = SCALE_WIDTH

   # defining the size
   max_size = int(size.strip())

   # defining the file name and the miniature file name
   basename, format = original_image_path.rsplit('.', 1)
   basename, name = basename.rsplit(os.path.sep, 1)

   miniature = name + '_' + str(max_size) + '.' + format
   thumbnail_path = os.path.join(basename, THUMBNAILS)
   if not os.path.exists(thumbnail_path):
       os.mkdir(thumbnail_path)

   miniature_filename = os.path.join(thumbnail_path, miniature)
   baseurl, crud = original_image_url.rsplit('/', 1)
   miniature_url = '/'.join((baseurl, THUMBNAILS, miniature))

   # if the image wasn't already resized, resize it
   if (not os.path.exists(miniature_filename)
       or os.path.getmtime(original_image_path) >
       os.path.getmtime(miniature_filename) ):
       image = Image.open(original_image_path)
       image_x, image_y = image.size

       if mode == SCALE_HEIGHT:
           image_y, image_x = scale(max_size, (image_y, image_x))
       else:
           image_x, image_y = scale(max_size, (image_x, image_y))


       image = image.resize((image_x, image_y), Image.ANTIALIAS)

       image.save(miniature_filename, image.format)

   return miniature_url
# vim: shiftwidth=4 tabstop=4 expandtab textwidth=72

More like this

  1. [UPDATE]Filter to resize a ImageField on demand by rafacdb 5 years, 8 months ago
  2. Twitter template tags and filters by moxypark 3 years, 8 months ago
  3. Quiet runserver by danielroseman 3 years, 10 months ago
  4. Filter to resize a ImageField on demand by michelts 7 years ago
  5. Cache Manager by jerzyk 6 years, 4 months ago

Comments

ludvig.ericson (on September 24, 2008):

Don't import your project's settings like that.

from django.conf import settings

#

(Forgotten your password?)