diff --git a/stdimage/fields.py b/stdimage/fields.py index e0ec390..ef5b567 100644 --- a/stdimage/fields.py +++ b/stdimage/fields.py @@ -4,7 +4,7 @@ from django.conf import settings from django.core.files.storage import FileSystemStorage from django.db.models import signals -from django.db.models.fields.files import ImageField +from django.db.models.fields.files import ImageField, FileDescriptor from forms import StdImageFormField from widgets import DelAdminFileWidget @@ -29,9 +29,15 @@ def url(self): def size(self): return self.storage.size(self.name) -class StdImageFileDescriptor( ImageFileDescriptor ): +class StdImageFileDescriptor( FileDescriptor ): def __set__( self, instance, value ): + previous_file = instance.__dict__.get( self.field.name ) super( StdImageFileDescriptor, self ).__set__( instance, value ) + if previous_file is not None: + self.field.update_dimension_fields( instance, force = True ) + signals.post_init.connect( self.field.update_dimension_fields, sender = instance.__class__ ) + signals.post_save.connect( self.field._rename_resize_image, sender = instance.__class__ ) + signals.post_init.connect( self.field._set_thumbnail, sender = instance.__class__ ) self.field._set_thumbnail( instance ) class StdImageField(ImageField): @@ -42,7 +48,7 @@ class StdImageField(ImageField): """ descriptor_class = StdImageFileDescriptor - def __init__(self, size=None, thumbnail_size=None, *args, **kwargs): + def __init__(self, *args, **kwargs): """Added fields: - size: a tuple containing width and height to resize image, and an optional boolean setting if is wanted forcing that size (None for not resizing). @@ -53,6 +59,9 @@ def __init__(self, size=None, thumbnail_size=None, *args, **kwargs): (None for not creating a thumbnail """ + size = kwargs.pop('size', None) + thumbnail_size = kwargs.pop('thumbnail_size', None) + params_size = ('width', 'height', 'force') for att_name, att in (('size', size), ('thumbnail_size', thumbnail_size)): @@ -100,6 +109,16 @@ def _resize_image(self, filename, size): img = Image.open(filename) if (img.size[WIDTH] > size['width'] or img.size[HEIGHT] > size['height']): + + #If the image is big resize it with the cheapest resize algorithm + factor = 1 + while (img.size[0]/factor > 2*size['width'] and + img.size[1]*2/factor > 2*size['height']): + factor *=2 + if factor > 1: + img.thumbnail((int(img.size[0]/factor), + int(img.size[1]/factor)), Image.NEAREST) + if size['force']: img = ImageOps.fit(img, (size['width'], size['height']), Image.ANTIALIAS)