Commits

George Notaras committed 82a8a7c

Several improvements regarding support for thumbnail options

Comments (0)

Files changed (4)

src/thumbnail_works/fields.py

 class Thumbnail:
     
     MANDATORY_OPTIONS = ['size']
-    VALID_OPTIONS = ['size', 'sharpen', 'detail', 'upscale']
+    DEFAULT_OPTIONS = {
+        'size': None,
+        'sharpen': False,
+        'detail': False,
+        'upscale': False,
+        }
     
     def __init__(self, name, options, source):
-        self.name = self._get_name(name)    # the thumbnail name as set in the dictionary
+        """
+        name: the thumbnail name as set in the 'thumbnails' dictionary
+        options: the thumbnail options as set in the 'thumbnails' dictionary
+
+        """
         if self._options_are_valid(options):
-            self.options = options
-        
-        self.size = options['size'] # size in the formn WIDTHxHEIGHT
-        self.width, self.height = get_width_height_from_string(self.size)
+            self.options = self._get_options(options)
+        self.name = self._get_name(name)
+        self.width, self.height = get_width_height_from_string(options['size'])
         self.url = make_thumbnail_path(source.url, self.name)
     
     # Private API
     def _get_name(self, name):
         return name.replace(' ', '_')
     
+    def _get_options(self, options):
+        """This method ensures that all the available options are set to a
+        value.
+        
+        """
+        thumb_options = self.DEFAULT_OPTIONS.copy()
+        thumb_options.update(options)
+        return thumb_options
+    
     def _options_are_valid(self, options):
         if not options.has_key('size'):
             raise ThumbnailOptionError('Thumbnail is missing the mandatory `size` option')
         for option in options.keys():
-            if option not in self.VALID_OPTIONS:
+            if option not in self.DEFAULT_OPTIONS.keys():
                 raise ThumbnailOptionError('Invalid thumbnail option `%s`' % option)
         return True
 
             for thumb_name, thumb_size in self.field.thumbnails.items():
                 #new_content = copy.deepcopy(content)
                 print "Doing: ", thumb_name, thumb_size
-                """
-                img_obj = ImageObject()
-                im = img_obj.get_img_data_from_file(content)
-                image_processors.resize(im, thumbnail_size)
-                thumbnail_content = img_obj.get_file_for_img_data(im)
-                """
+
                 processed_content = process_content_as_image(
                     content, resize_to=thumb_size, sharpen=True)
                 thumb_path = make_thumbnail_path(source_path, thumb_name)
                 print thumb_path
                 thumb_path_saved = self.storage.save(thumb_path, processed_content)
                 
-                assert thumb_path == thumb_path_saved, 'Calculated thumbnail \
-                path `%s` and the actual path where the thumbnail was saved \
-                `%s` differ.'
+                assert thumb_path == thumb_path_saved, 'The calculated \
+                thumbnail path `%s` and the actual path where the thumbnail \
+                was saved `%s` differ.'
     
                 
     def delete(self, save=True):
         Accepts regular ImageField keyword arguments and also:
         
         ``resize_source``
-            A string of the WIDTHxHEIGHT which represents the size to which
-            the uploaded image will be resized before saved to the storage.
-            If not set, the uploaded image is not resized.
+            A dictionary of thumbnail options as described below. If this is
+            set, these options will be used for source image resize.
+            Contrariwise, if this is not set, the uploaded image is saved in
+            its original form, unless THUMBNAILS_FORCE_SOURCE_FORMAT is set,
+            in which case the source image is saved in the specified format. 
         ``thumbnails``
             A dictionary of thumbnail definitions. The format of each
             thumbnail definition is::

src/thumbnail_works/image_processors.py

 def sharpen(im):
     im = im.filter(ImageFilter.SHARPEN)
     return im
+
+def detail(im):
+    im = im.filter(ImageFilter.DETAIL)
+    return im
+

src/thumbnail_works/settings.py

 from django.conf import settings
 
 
+# If THUMBNAILS_FORCE_FORMAT is set to True, then the uploaded image is 
+THUMBNAILS_FORCE_SOURCE_FORMAT = getattr(settings, 'DTW_THUMBNAILS_FORCE_SOURCE_FORMAT', None)
+
 # JPEG, PNG
 THUMBNAILS_FORMAT = getattr(settings, 'DTW_THUMBNAILS_FORMAT', 'JPEG')
 
-# If THUMBNAILS_FORCE_FORMAT is set to True, then the uploaded image is 
-#THUMBNAILS_FORCE_SOURCE_FORMAT
-
 # For JPEG format only
 THUMBNAILS_QUALITY = getattr(settings, 'DTW_THUMBNAILS_QUALITY', 85)
 

src/thumbnail_works/utils.py

     return size_x, size_y
 
 
-def get_thumbnail_path(source_path, thumbnail_name):
+def make_thumbnail_path(source_path, thumbnail_name):
     """
+    THUMBNAILS_DIRNAME
     For urls and filesystem paths
     
-    source: /media/images/photo.jpg
+    source_path: /media/images/photo.jpg
     thumbnail: /media/images/photo.<thumbname>.jpg
     """
     root_dir = os.path.dirname(source_path)  # /media/images
     return os.path.join(root_dir, '%s.%s.%s' % (base_filename, thumbnail_name, ext))
 
 
-def process_content_as_image(content, resize_to=None, sharpen=False):
+def process_content_as_image(content, size=None, sharpen=False,
+        format=settings.THUMBNAILS_FORMAT):
     
     # Image.open() accepts a file-like object, but it is needed
     # to rewind it back to be able to get the data,
         im = im.convert('RGB')
     
     # Process
-    if resize_to is not None:
-        im = image_processors.resize(im, get_width_height_from_string(resize_to))
+    if size is not None:
+        new_size = get_width_height_from_string(size)
+        im = image_processors.resize(im, new_size)
     if sharpen:
         im = image_processors.sharpen(im)
     
-    io = StringIO.StringIO()
+    # Save image data
+    buffer = StringIO.StringIO()
     
-    if settings.THUMBNAILS_FORMAT == 'JPEG':
-        im.save(io, 'JPEG', quality=settings.THUMBNAILS_QUALITY)
-    elif settings.THUMBNAILS_FORMAT == 'PNG':
-        im.save(io, 'PNG')
+    if format == 'JPEG':
+        im.save(buffer, 'JPEG', quality=settings.THUMBNAILS_QUALITY)
+    elif format == 'PNG':
+        im.save(buffer, 'PNG')
     
-    return ContentFile(io.getvalue())
+    data = buffer.getvalue()
+    
+    return ContentFile(data)