Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Padded fit with easy thumbnails

I'm using easy-thumbnails to make thumbnails for my site. I want to create a thumbnail from an image that's 1500x1023px. The size of the desired thumbnail is 100x100px. What I want is for the thumbnail to show the entire logo rather than cropping or stretching. I've seen this referred to as a padded fit - kind the opposite of a crop. For example, for this image, we'd add 236px of whitespace on the top and 237px of whitespace on the bottom and then resize. Is there any way to do this with easy-thumbnails? If not, any suggestions on how to approach this? Thanks!

like image 616
Josh Avatar asked Aug 14 '12 20:08

Josh


2 Answers

Thanks for Timmy O'Mahony's suggestion of creating a processor to do the padding. Here's the code for those of you that come up against a similar issue. To get this to work, you'll need something like this in settings:

THUMBNAIL_PROCESSORS = (
    'easy_thumbnails.processors.colorspace',
    'common.thumbnail_processors.pad_image',
    'easy_thumbnails.processors.autocrop',
    'easy_thumbnails.processors.scale_and_crop',
    'easy_thumbnails.processors.filters')

And then you can add this to common/thumbnail_processors.py (or wherever)

import Image

def pad_image(image, **kwargs):
    """ Pad an image to make it the same aspect ratio of the desired thumbnail.
    """

    img_size = image.size
    des_size = kwargs['size']
    fit = [float(img_size[i])/des_size[i] for i in range(0,2)]

    if fit[0] > fit[1]:
        new_image = image.resize((image.size[0],
            int(round(des_size[1]*fit[0]))))
        top = int((new_image.size[1] - image.size[1])/2)
        left = 0
    elif fit[0] < fit[1]:
        new_image = image.resize((int(round(des_size[0]*fit[1])), 
            image.size[1]))
        top = 0
        left = int((new_image.size[0] - image.size[0])/2)
    else:
        return image

    # For transparent
    #mask=Image.new('L', new_image.size, color=0)
    #new_image.putalpha(mask)

    # For white
    new_image.paste((255, 255, 255, 255))

    new_image.paste(image, (left, top))
    return new_image
like image 131
Josh Avatar answered Sep 16 '22 11:09

Josh


Thanks a lot for that answer, Josh! This is exactly what I was looking for since a few weeks. However, your solution mysteriously doesn't work on some images.

Here is a (fully functionnal) revised version of that thumbnail processor: https://bitbucket.org/bercab/cmsplugin-nivoslider/src/b07db53c1ce4/cmsplugin_nivoslider/thumbnail_processors.py

like image 33
Bertrand Bordage Avatar answered Sep 20 '22 11:09

Bertrand Bordage