Does Python PIL resize maintain the aspect ratio?

Question:

Does PIL resize to the exact dimensions I give it no matter what? Or will it try to keep the aspect ratio if I give it something like the Image.ANTIALIAS argument?

Asked By: frederix

||

Answers:

How do I resize an image using PIL and maintain its aspect ratio?

Image.resize from PIL will do exactly as told. No behind scenes aspect ratio stuff.

Answered By: Kugel

Yes it will keep aspect ratio using thumbnail method:

image = Image.open(source_path)
image.thumbnail(size, Image.ANTIALIAS)
image.save(dest_path, "JPEG")
Answered By: Maksym Kozlenko

Yes. the thumbnail() method is what is needed here… One thing that hasn’t been mentioned in this or other posts on the topic is that ‘size’ must be either a list or tuple. So, to resize to a maximum dimension of 500 pixels, you would call:
image.thumbnail((500,500), Image.ANTIALIAS)

See also this post on the subject:
How do I resize an image using PIL and maintain its aspect ratio?

Answered By: Luke

No, it does not. But you can do something like the following:

im = PIL.Image.open("email.jpg"))
width, height = im.size
im = im.resize((width//2, height//2))

Here the height and width are divided by the same number, keeping the same aspect ratio.

Answered By: Lahiru Karunaratne

Okay, so this requires a couple of lines of code to get what you want.

First you find the ratio, then you fix a dimension of the image that you want (height or width). In my case, I wanted height as 100px and let the width adjust accordingly, and finally use that ratio to find new height or new width.

So first find the dimensions:

width, height = logo_img.size
ratio = width / height
      

Then, fix one of the dimension:

new_height = 100

Then find new width for that height:

new_width = int(ratio * new_height)
            
logo_img = logo_img.resize((new_width, new_height))
Answered By: Shreyas Vedpathak

Recent Pillow version (since 8.3) have the following method to have an image resized to fit in given box with keeping aspect ratio.

image = ImageOps.contain(image, (2048,2048))
Answered By: fabien-michel

I think following is the easiest way to do:

Img1 = img.resize((img.size),PIL.Image.ANTIALIAS)
Answered By: Sourabh Verma

It depends on your demand, if you want you can set a fixed height and width or if you want you can resize it with aspect-ratio.

For the aspect-ratio-wise resize you can try with the below codes :

To make the new image half the width and half the height of the original image:

from PIL import Image
im = Image.open("image.jpg")
resized_im = im.resize((round(im.size[0]*0.5), round(im.size[1]*0.5)))
        
#Save the cropped image
resized_im.save('resizedimage.jpg')

To resize with fixed width and ratio wise dynamic height :

from PIL import Image
new_width = 300
im = Image.open("img/7.jpeg")
concat = int(new_width/float(im.size[0]))
size = int((float(im.size[1])*float(concat)))
resized_im = im.resize((new_width,size), Image.ANTIALIAS)
#Save the cropped image
resized_im.save('resizedimage.jpg')
Answered By: Ruhul Amin

Recent versions of Pillow have some useful methods in PIL.ImageOps.

Depending on exactly what you’re trying to achieve, you may be looking for one of these:

  • ImageOps.fit(image, size [, …]) (docs) – resizes your image, maintaining its aspect ratio, and crops it to fit the given size

  • ImageOps.contain(image, size [, …]) (docs) – resizes your image, maintaining its aspect ratio, so that it fits within the given size

Answered By: talljosh

One complete example:

import PIL.Image


class ImageUtils(object):
    @classmethod
    def resize_image(cls, image: PIL.Image.Image, width=None, height=None) -> PIL.Image.Image:
        if height is None and width is not None:
            height = image.height * width // image.width
        elif width is None and height is not None:
            width = image.width * height // image.height
        elif height is None and width is None:
            raise RuntimeError("At lease one of width and height must be present")
        return image.resize((width, height))


def main():
    ImageUtils.resize_image(PIL.Image.open("old.png"), width=100).save("new.png")


if __name__ == '__main__':
    main()

Answered By: BaiJiFeiLong