Explain Codes LogoExplain Codes Logo

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

python
image-processing
aspect-ratio
resampling
Anton ShumikhinbyAnton Shumikhin·Oct 31, 2024
TLDR

To maintain aspect ratio when resizing an image with Pillow, compute the proportional height: new_height = int(original_height * (new_width / original_width)). Use resize() to apply this:

from PIL import Image def resize_aspect_ratio(image_path, new_width): img = Image.open(image_path) original_width, original_height = img.size new_height = int(original_height * (new_width / original_width)) resized_img = img.resize((new_width, new_height), Image.ANTIALIAS) resized_img.save('resized_image.jpg') resize_aspect_ratio('path_to_your_cool_image.jpg', 300) # Don't forget to specify the image path and new width

This keeps the aspect ratio intact, with 300 as the new width; you can replace it with your desired width.

Simplifying with thumbnail()

Automating aspect ratio maintenance

Try the Image.thumbnail() function that automates aspect ratio maintenance:

def thumbnail_aspect_ratio(image_path, max_size): img = Image.open(image_path) img.thumbnail(max_size, Image.Resampling.LANCZOS) # For the lovers of high quality img.save('please_dont_sue_me_Disney.jpg') thumbnail_aspect_ratio('path_to_your_full_sized_princess_image.jpg', (300,300)) # Max size method makes resizing a piece of cake!

Focusing on width or height

Main characters should always be in focus, right? If you want to prioritize width or height, use this:

def resize_by_width(image_path, base_width): img = Image.open(image_path) w_percent = (base_width / float(img.size[0])) h_size = int((float(img.size[1]) * float(w_percent))) img = img.resize((base_width, h_size), Image.Resampling.LANCZOS) img.save('no_more_fat_cats.jpg') resize_by_width('path_to_your_leonardo_dicaprio.jpg', 300) # Because DiCaprio deserves the width!

Overwriting the original filename

If you're a brave programmer who doesn't fear overwriting originals, do it this way:

resized_img.save(image_path) # Be brave, overwrite the original file

Mastering the edge situations

Resizing larger images

When resizing a powerful giants like 4K images into a 128x128 dwarfs, consider a two-step resize to keep details.

Prioritizing quality

Love quality? Choose the resampling method wisely from the available options:

  • Image.NEAREST is the Usain Bolt of resampling methods, but don't expect a van Gogh masterpiece.
  • Image.LANCZOS, the Benedict Cumberbatch of resampling, gives a balance between quality and performance.
  • Once upon a time, Image.ANTIALIAS was high quality. Now Image.Resampling.LANCZOS is the new hot thing.

The magic of format change

Bored of one format? Change it using:

resized_img.save('get_me_a_new_look.png', format='PNG') # Becomes a PNG file

Visualization

Resizing is akin to sizing a picture into a new frame while not cropping:

An Artwork: |🖼️| (Size: 400x300) The New Frames: |📏| (Width based: 200x?) |📐| (Height based: ?x150)

Give your picture a new, snugly fitting size:

Width based: |🖼️📐| (200x150) Height based: |🖼️📏| (200x150)

Now the artwork maintains the original proportions inside the new frames:

Viewpoints: |🖼️| = |🖼️📐| = |🖼️📏|

Art isn't supposed to stretch or squash, is it?

Taking care of all orientations and aspect ratios

Portrait, landscape or just square

Not all pictures come with the same orientation, right? Be aware!

def resize_adaptive(image_path, base_dimension): img = Image.open(image_path) if img.size[0] > img.size[1]: # Do you see the landscape? return resize_by_width(image_path, base_dimension) else: # Or is it a portrait or a square? return resize_by_height(image_path, base_dimension)

When the aspect ratio looks weird

Sometimes the pictures are too wide or tall. Be careful with extreme size changes!

Remember the memory!

When processing multiple images, memory can start grumbling.

After saving the resized image, if you prefer peace and quiet over an angry memory, free resources using the img.close() method!

Check the References section if you ever panic. Remember that practice makes perfect! Vote if you find this helpful + it might help me afford a coffee. No pressure though. Happy coding!👩‍💻