UPDATED: 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
THUMBNAILS = 'thumbnails'
SCALE_WIDTH = 'w'
SCALE_HEIGHT = 'h'

def scale(max_x, pair):
    x, y = pair
    new_y = (float(max_x) / x) * y
    return (int(max_x), int(new_y))
    
# Thumbnail filter based on code from http://batiste.dosimple.ch/blog/2007-05-13-1/
@register.filter
def thumbnail(original_image_path, arg):  
    if not original_image_path:  
        return ''  
        
    if arg.find(','):
        size, upload_path = [a.strip() for a in  arg.split(',')]
    else:
        size = arg
        upload_path = ''

    if (size.lower().endswith('h')):
        mode = 'h'
    else:
        mode = 'w'
        
    # defining the size  
    size = size[:-1]
    max_size = int(size.strip())
    
    # defining the filename and the miniature filename  
    basename, format = original_image_path.rsplit('.', 1)  
    basename, name = basename.rsplit(os.path.sep, 1)  

    miniature = name + '_' + str(max_size) + mode + '.' + 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)  
    miniature_url = '/'.join((settings.MEDIA_URL, upload_path, 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  

More like this

  1. Auto Generate/Save Thumbnails using Template Filter (scale max_x, max_y, or both) by ThisbeTom 5 years, 4 months ago
  2. [UPDATE]Filter to resize a ImageField on demand by rafacdb 5 years, 8 months ago
  3. iPernity thumbnail helper by sedden 5 years, 5 months ago
  4. Template Tag of Django Image Thumb Creator by ayang23 3 years, 2 months ago
  5. Improved many-page pagination by dokterbob 3 years, 7 months ago

Comments

Eftarjin (on November 3, 2007):

miniature_url = os.path.join(settings.MEDIA_URL, upload_path, THUMBNAILS, miniature)

It may not be a good idea to use os.path.join (which is platform-specific) to build URLs.

I suggest to use '/'.join instead. (The separator for URLs is always '/', whatever platform you're on)

#

danfairs (on November 7, 2007):

Ah - good point. I'm too hard-wired into thinking of filesystem paths! I'll update the sample. Thanks.

#

vladka (on July 21, 2011):

i'd thing you're should also add: if not os.path.exists(original_image_path): return ''

because source image can be deleted, or move and etc.

thank you for you snippet.

#

(Forgotten your password?)