Erez
Erez

Reputation: 1953

Why does PIL thumbnail not resizing correctly?

I am trying to create and save a thumbnail image when saving the original user image in the userProfile model in my project, below is my code:

def save(self, *args, **kwargs):
    super(UserProfile, self).save(*args, **kwargs)
    THUMB_SIZE = 45, 45
    image = Image.open(join(MEDIA_ROOT, self.headshot.name))

    fn, ext = os.path.splitext(self.headshot.name)
    image.thumbnail(THUMB_SIZE, Image.ANTIALIAS)        
    thumb_fn = fn + '-thumb' + ext
    tf = NamedTemporaryFile()
    image.save(tf.name, 'JPEG')
    self.headshot_thumb.save(thumb_fn, File(open(tf.name)), save=False)
    tf.close()

    super(UserProfile, self).save(*args, **kwargs)

Every thing is working OK, just this one thing.

The problem is that the thumbnail function only sets the width to 45 and doesn't change the ratio aspect of the image so I am getting an image of 45*35 for the one that I am testing on (short image).

Can any one tell me what am I doing wrong? How to force the aspect ratio I want?

P.S.: I've tried all the methods for size: tupal: THUMB_SIZE = (45, 45) and entering the sizes directly to the thumbnail function also.

Another question: what is the deference between resize and thumbnail functions in PIL? When to use resize and when to use thumbnail?

Upvotes: 6

Views: 7979

Answers (2)

tzot
tzot

Reputation: 95971

Given:

import Image # Python Imaging Library
THUMB_SIZE= 45, 45
image # your input image

If you want to resize any image to size 45×45, you should use:

new_image= image.resize(THUMB_SIZE, Image.ANTIALIAS)

However, if you want a resulting image of size 45×45 while the input image is resized keeping its aspect ratio and filling the missing pixels with black:

new_image= Image.new(image.mode, THUMB_SIZE)
image.thumbnail(THUMB_SIZE, Image.ANTIALIAS) # in-place
x_offset= (new_image.size[0] - image.size[0]) // 2
y_offset= (new_image.size[1] - image.size[1]) // 2
new_image.paste(image, (x_offset, y_offset))

Upvotes: 6

BFil
BFil

Reputation: 13096

The image.thumbnail() function will maintain the aspect ratio of the original image.

Use image.resize() instead.

UPDATE

image = image.resize(THUMB_SIZE, Image.ANTIALIAS)        
thumb_fn = fn + '-thumb' + ext
tf = NamedTemporaryFile()
image.save(tf.name, 'JPEG')

Upvotes: 13

Related Questions