Question

import Image

image  = Image.open('images/original.jpg')
width  = image.size[0]
height = image.size[1]

if width > height:
    difference = width - height
    offset     = difference / 2
    resize     = (offset, 0, width - offset, height)

else:
    difference = height - width
    offset     = difference / 2
    resize     = (0, offset, width, height - offset)

thumb = image.crop(resize).resize((200, 200), Image.ANTIALIAS)
thumb.save('thumb.jpg')

This is my current thumbnail generation script. The way it works is:

If you have an image that is 400x300 and you want a thumbnail that's 100x100, it will take 50 pixels off the left and right side of the original image. Thus, resizing it to be 300x300. This gives the original image the same aspect ratio as the new thumbnail. After that, it will shrink it down to the required thumbnail size.

The advantages of this is:

  • The thumbnail is taken from the center of the image
  • Aspect ratio doesn't get screwed up

If you were to shrink the 400x300 image down to 100x100, it will look squished. If you took the thumbnail from 0x0 coordinates, you would get the top left of the image. Usually, the focal point of the image is the center.

What I want to be able to do is give the script a width/height of any aspect ratio. For example, if I wanted the 400x300 image to be resized to 400x100, it should shave 150px off the left and right sides of the image...

I can't think of a way to do this. Any ideas?

Was it helpful?

Solution

You just need to compare the aspect ratios - depending on which is larger, that will tell you whether to chop off the sides or the top and bottom. e.g. how about:

import Image

image  = Image.open('images/original.jpg')
width  = image.size[0]
height = image.size[1]

aspect = width / float(height)

ideal_width = 200
ideal_height = 200

ideal_aspect = ideal_width / float(ideal_height)

if aspect > ideal_aspect:
    # Then crop the left and right edges:
    new_width = int(ideal_aspect * height)
    offset = (width - new_width) / 2
    resize = (offset, 0, width - offset, height)
else:
    # ... crop the top and bottom:
    new_height = int(width / ideal_aspect)
    offset = (height - new_height) / 2
    resize = (0, offset, width, height - offset)

thumb = image.crop(resize).resize((ideal_width, ideal_height), Image.ANTIALIAS)
thumb.save('thumb.jpg')
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top