How do I make PIL take into account the shortest side when creating a thumbnail?
Currently, for my function below...the image will be resized based on the longest side.
Basically the image has a larger height, the height will be 200px. The width will be just...whatever...
If the image has a larger width, the width will be 200px, and the height will adjust accordingly.
How do I flip this around!? I want this function to take into account the shortest side.
Am I writing this function incorrectly??
def create_thumbnail(f, width=200, height=None, pad = False): #resizes the longest side!!! doesn't even care about the shortest side #this function maintains aspect ratio. if height==None: height=width im = Image.open(StringIO(f)) imagex = int(im.size) imagey = int(im.size) if imagex < width or imagey < height: pass #return None if im.mode not in ('L', 'RGB', 'RGBA'): im = im.convert('RGB') im.thumbnail((width, height), Image.ANTIALIAS) thumbnail_file = StringIO() im.save(thumbnail_file, 'JPEG') thumbnail_file.seek(0) return thumbnail_file
Use resize instead of thumbnail.
The point behind thumbnail is to make it easy to scale an image down to fit within a particular bounding box preserving aspect ratio. That means that if your bounding box is a square, the longer side of the image determines the scale used.
resize gives you more direct control -- you specify exactly what size you want.
Actually, since you want to preserve aspect you could still use thumbnail, but you need to fudge the bounding box. Before your call to thumbnail, try doing this:
old_aspect = float(imagex)/float(imagey) new_aspect = float(width)/float(height) if old_aspect < new_aspect: height = int(width / old_aspect) else: width = int(height * old_aspect)
i put together this function a while ago:
def thumbnail(img, size=150): from math import floor from PIL import Image img = img.copy() if img.mode not in ('L', 'RGB'): img = img.convert('RGB') width, height = img.size if width == height: img.thumbnail((size, size), Image.ANTIALIAS) elif height > width: ratio = float(width) / float(height) newwidth = ratio * size img = img.resize((int(floor(newwidth)), size), Image.ANTIALIAS) elif width > height: ratio = float(height) / float(width) newheight = ratio * size img = img.resize((size, int(floor(newheight))), Image.ANTIALIAS) return img image = thumbnail(image, size=600)
it resizes an image down to at most size on its longest size preserving aspect ratio