Login

Image Standarization

Author:
garcia_marc
Posted:
April 15, 2008
Language:
Python
Version:
.96
Tags:
image thumbnail resize rename
Score:
3 (after 3 ratings)

Standarization of image fields (for being used when saving models). Automatically creates thumbnail. Change image name to /path/to/images/<my_field>-<id>.<ext>. Resize image and thumbnail to specified size (optionally can crop image to force size).

 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
def stdimg(instance, image, thumbnail, force_size=False):
  '''
    standarization of image fields (for being used when saving models)
      automatically creates thumbnail
      change image name to /path/to/images/<my_field>-<id>.<ext>
      resize image to specified size
    arguments:
      instance: model instance to be saved
      image: tuple containing image field name, and desired size (a tuple containing width and height)
      thumbnail: tuple containing thumbnail field name, and desired size (a tuple containing width and height)
    example:
      class MyModel(models.Model):
        my_image = models.ImageField(upload_to='path/to/images')
        my_thumbnail = models.ImageField(upload_to='path/to/thumbnails', editable=False)

        def save(self):
          super(MyClass, self).save() # We force to save and create an object id to use in image name
          stdimg(self, ('my_image', (640, 480)), ('my_thumbnail', (100, 75)))
          super(MyClass, self).save() # We update paths on db
  '''
  import os
  from django.conf import settings
  from PIL import Image
  src = eval('instance.get_%s_filename()' % image[0])
  if src:
    ext = os.path.splitext(src)[1].lower().replace('jpg', 'jpeg')
    filename = lambda s: instance._meta.get_field(s).get_filename('%s-%s%s' % (s, instance.id, ext))

    for field in (image, thumbnail):
      img = Image.open(src)
      if force_size:
        size = field[1]
        ratio = lambda t: float(t[1]) / float(t[0])
        if ratio(size) > ratio(img.size):
          x, y = float(img.size[0]) / img.size[1] * size[1], size[1]
          pos_x, pos_y = float(x - size[0]) / 2, 0
        else:
          x, y = size[0], float(img.size[1]) / img.size[0] * size[0]
          pos_x, pos_y = 0, float(y - size[1]) / 2
        img = img.resize((x,y), Image.ANTIALIAS)
        img = img.crop((pos_x, pos_y, pos_x + size[0], pos_y + size[1]))
      else:
        img.thumbnail(field[1], Image.ANTIALIAS)
      img.save(settings.MEDIA_ROOT + filename(field[0]))
      setattr(instance, field[0], filename(field[0]))

    if os.path.exists(src) and src != settings.MEDIA_ROOT + filename(image[0]):
      os.remove(src)

More like this

  1. [UPDATE]Filter to resize a ImageField on demand by rafacdb 6 years, 11 months ago
  2. Filter to resize a ImageField on demand by michelts 8 years, 3 months ago
  3. Auto Generate/Save Thumbnails using Template Filter (scale max_x, max_y, or both) by ThisbeTom 6 years, 7 months ago
  4. Resize image on save by David 7 years, 3 months ago
  5. ThumbnailMixIn by johan 6 years, 3 months ago

Comments

ffsffd (on January 5, 2011):

eval('instance.get_%s_filename()' % image[0]) should be written as getattr(instance, 'get_%s_filename' % image[0])()

#

Please login first before commenting.