How to Resize an Image Using Pil and Maintain Its Aspect Ratio

Does Python PIL resize maintain the aspect ratio?

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.

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

Define a maximum size.
Then, compute a resize ratio by taking min(maxwidth/width, maxheight/height).

The proper size is oldsize*ratio.

There is of course also a library method to do this: the method Image.thumbnail.

Below is an (edited) example from the PIL documentation.

import os, sys
import Image

size = 128, 128

for infile in sys.argv[1:]:
outfile = os.path.splitext(infile)[0] + ".thumbnail"
if infile != outfile:
try:
im = Image.open(infile)
im.thumbnail(size, Image.ANTIALIAS)
im.save(outfile, "JPEG")
except IOError:
print "cannot create thumbnail for '%s'" % infile

How to resize images without keeping the aspect ratio?

From the documenation on Image.thumbnail:

This method calculates an appropriate thumbnail size to preserve the aspect of the image, [...]

So, why not using Image.resize for that task?

from PIL import Image

img = Image.open('path/to/some/image.png')
print(img)
# ... size=400x400

img_thumb = img.copy()
img_thumb.thumbnail(size=(300, 200))
print(img_thumb)
# ... size=200x200

img_resize = img.resize((300, 200))
print(img_resize)
# ... size=300x200

Image.resize will (forcefully) resize any image to the given size.

----------------------------------------
System information
----------------------------------------
Platform: Windows-10-10.0.16299-SP0
Python: 3.9.1
PyCharm: 2021.1.1
Pillow: 8.2.0
----------------------------------------

Resize image maintaining aspect ratio AND making portrait and landscape images exact same size?

Here is my take on doing a padded fit for an image:

#!/usr/bin/env python

from PIL import Image, ImageChops

F_IN = "/path/to/image_in.jpg"
F_OUT = "/path/to/image_out.jpg"

size = (80,80)

image = Image.open(F_IN)
image.thumbnail(size, Image.ANTIALIAS)
image_size = image.size

thumb = image.crop( (0, 0, size[0], size[1]) )

offset_x = max( (size[0] - image_size[0]) / 2, 0 )
offset_y = max( (size[1] - image_size[1]) / 2, 0 )

thumb = ImageChops.offset(thumb, offset_x, offset_y)
thumb.save(F_OUT)

It first uses the thumbnail operation to bring the image down to within your original bounds and preserving the aspect. Then it crops it back out to actually fill the size of your bounds (since unless the original image was square, it will be smaller now), and we find the proper offset to center the image. The image is offset to the center, so you end up with black padding but no image cropping.

Unless you can make a really sensible guess at a proper center crop without losing possible important image data on the edges, a padded fit approach will work better.

Update

Here is a version that can do either center crop or pad fit.

#!/usr/bin/env python

from PIL import Image, ImageChops, ImageOps

def makeThumb(f_in, f_out, size=(80,80), pad=False):

image = Image.open(f_in)
image.thumbnail(size, Image.ANTIALIAS)
image_size = image.size

if pad:
thumb = image.crop( (0, 0, size[0], size[1]) )

offset_x = max( (size[0] - image_size[0]) / 2, 0 )
offset_y = max( (size[1] - image_size[1]) / 2, 0 )

thumb = ImageChops.offset(thumb, offset_x, offset_y)

else:
thumb = ImageOps.fit(image, size, Image.ANTIALIAS, (0.5, 0.5))

thumb.save(f_out)


source = "/path/to/source/image.JPG"

makeThumb(source, "/path/to/source/image_padded.JPG", pad=True)
makeThumb(source, "/path/to/source/image_centerCropped.JPG", pad=False)

PIL how to resize image to fill up height and width dimension

Reason I was getting the black borders was because of the new_img. The image gets stretched out right after resize() so I saved the image right after.

from PIL import Image
import os, sys
import uuid
#input path
path = "data/oyaku_don_source/"
dirs = os.listdir( path )
final_size = 244;

def resize_image():
for item in dirs:
if item == '.DS_Store':
continue
if os.path.isfile(path+item):
im = Image.open(path+item)
f, e = os.path.splitext(path+item)
size = im.size
ratio = float(final_size) / max(size)
new_image_size = tuple([int(x*ratio) for x in size])
im = im.resize((244, 244), Image.ANTIALIAS)
#output path with a unique id
im.save('data/Oyaku_Don/'+str(uuid.uuid4().fields[-1])[:5]+'.jpg', 'JPEG', quality=90)

Python PIL - Resize Images

Use userImage = userImage.resize(size), because resize() returns a copy of the image, resized; it doesn't actively resize the image.

size = (1080, 1080)
userImage = Image.open(f"./Images/UsersImages/001.png")
userImage = userImage.resize(size) ### EDITED LINE
userImage.show()

Python / Pillow: How to scale an image

Noo need to reinvent the wheel, there is the Image.thumbnail method available for this:

maxsize = (1028, 1028)
image.thumbnail(maxsize, PIL.Image.ANTIALIAS)

Ensures the resulting size is not bigger than the given bounds while maintains the aspect ratio.

Specifying PIL.Image.ANTIALIAS applies a high-quality downsampling filter for better resize result, you probably want that too.

PIL: Paste image with resized aspect ratio

Use resize after read the icon image to fit the desired size:

from PIL import Image, ImageDraw

iconSize=(200,100)
icon = Image.open("./icon.png")
icon=icon.resize(iconSize)
background = Image.open("./background.png")

mask = Image.new("L", icon.size, 0)
draw = ImageDraw.Draw(mask)
draw.ellipse((0, 0) + icon.size, fill=255)


back_im = background.copy()
# back_im.paste(icon, iconSize, mask=mask)
back_im.paste(icon, icon.size, mask=mask)
back_im.save("./back_im.png")


Related Topics



Leave a reply



Submit