43

Suppose I have an image which is 2322px x 4128px. How do I scale it so that both the width and height are both less than 1028px?

I won't be able to use Image.resize since that requires me to give both the new width and height. What I plan to do is (pseudo code below):

if (image.width or image.height) > 1028:
    if image.width > image.height:
        tn_image = image.scale(make width of image 1028)
        # since the height is less than the width and I am scaling the image
        # and making the width less than 1028px, the height will surely be
        # less than 1028px
    else: #image's height is greater than it's width
        tn_image = image.scale(make height of image 1028)

I am guessing I need to use Image.thumbnail, but according to this example and this answer, both the width and the height are provided in order to create the thumbnail. Is there any function which takes either the new width or the new height (not both) and scales the entire image?

buhtz
  • 10,774
  • 18
  • 76
  • 149
SilentDev
  • 20,997
  • 28
  • 111
  • 214
  • 2
    Where is a problem with providing both width and height to `Image.thumbnail`? You want to do exactly that with your custom code. – famousgarkin Jul 14 '14 at 21:13

2 Answers2

91

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.

sequoia
  • 143
  • 1
  • 8
famousgarkin
  • 13,687
  • 5
  • 58
  • 74
  • 3
    oh, I misunderstood what thumbnail does. I thought image.thumbnail(1028, 1028) resizes the image to 1028 width and 1028 height... I didn't know image.thumbnail(1028, 1028) scales the image so that both the width and height are less than 1028 – SilentDev Jul 14 '14 at 21:17
  • 2
    @user2719875 I would strongly suggest adding the `Image.ANTIALIAS` parameter. – Mark Ransom Jul 14 '14 at 21:24
  • 4
    If using Pillow >= 2.5.0, `Image.ANTIALIAS` is the [default](https://github.com/python-pillow/Pillow/commit/22a370afc219af47907b2fe69e791854dd2d9c79) for `Image.thumbnail()`. – Hugo Jul 16 '14 at 23:05
  • 2
    Notice that according to the [documentation](https://pillow.readthedocs.io/en/3.1.x/reference/Image.html#PIL.Image.Image.thumbnail) "Note that this function modifies the Image object in place. If you need to use the full resolution image as well, apply this method to a copy() of the original image." – mapto Feb 20 '18 at 11:17
21

Use Image.resize, but calculate both width and height.

if image.width > 1028 or image.height > 1028:
    if image.height > image.width:
        factor = 1028 / image.height
    else:
        factor = 1028 / image.width
    tn_image = image.resize((int(image.width * factor), int(image.height * factor)))
GG2C
  • 3
  • 4
Sohcahtoa82
  • 619
  • 3
  • 13