Search code examples
pythonpython-3.xpython-imaging-libraryimage-resizing

How to resize images without keeping the aspect ratio?


I tried a lot of ways to resize an image forcefully according to the width and height value, but it always returns maybe with an aspect ratio which I don't expect.

I have a few images, and I wanted to find out the average width and height pixel value, then according to those average pixel value, I expected to resize the whole images.

Here is the code I tried to calculate average pixel:

from PIL import Image, ImageOps

listofimages = ['one.jpg', 'two.jpg', 'three.jpg','four.jpg', 'five.jpg', 'six.jpg']

def get_avg_size(listofimages):
    h, w = 0, 0
    for p in listofimages:
        im = Image.open(p)
        width, height = im.size
        h += height
        w += width
        print('Process image {0} and height-weight is {1} '.format(p, im.size))

    print('Calculate average w-h: {0} ~ {1}'.format(w //len(listofimages), h//len(listofimages)))
    return w//len(listofimages), h//len(listofimages)

Then resize all the images:

def _convert_in_same_size(width, height, listofimages):
    sizes = width, height
    for p in listofimages:
        images = Image.open(p)
        images.thumbnail(sizes, Image.ANTIALIAS)
        images.save(p)
        print('Saved image {0} and size is {1}'.format(p, sizes))

Get the result:

get_width, get_height = get_avg_size(listofimages)
_convert_in_same_size(get_width, get_height, listofimages)

Output

Process image one.jpg and height-weight is (771, 480) 
Process image two.jpg and height-weight is (480, 270) 
Process image three.jpg and height-weight is (800, 484) 
Process image four.jpg and height-weight is (522, 340) 
Process image five.jpg and height-weight is (1200, 900)
Process image six.jpg and height-weight is (1000, 667)

Calculate average w-h: 795 ~ 523

Saved image one.jpg and size is (795, 523)
Saved image two.jpg and size is (795, 523)
Saved image three.jpg and size is (795, 523)
Saved image four.jpg and size is (795, 523)
Saved image five.jpg and size is (795, 523)
Saved image six.jpg and size is (795, 523)

Showing the result size is (795, 523) but the reality is every single image keeps an aspect ratio. If I check again after resizing the images

Process image one.jpg and height-weight is (771, 480)
Process image two.jpg and height-weight is (480, 270)
Process image three.jpg and height-weight is (795, 481)
Process image four.jpg and height-weight is (522, 340)
Process image five.jpg and height-weight is (697, 523)
Process image six.jpg and height-weight is (784, 523)

I don't expect any aspect ratio, and forcefully resize all the images with the average(795 ~ 523) pixel. How can I do that?


Solution

  • 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
    ----------------------------------------