Welcome, guest | Sign In | My Account | Store | Cart

Resize a rectangle (ie.: an image) while keeping the aspect ratio, without float.

You can scale up and down the proportions so the edges will be either at most or at least the given one.

Python, 6 lines
1
2
3
4
5
6
def scale(w, h, x, y, maximum=True):
        nw = y * w / h
        nh = x * h / w
        if maximum ^ (nw >= x):
                return nw or 1, y
        return x, nh or 1

The code is really short, but it somehow gave me a headache.

Thank's to Maz http://maz.p0d.org for helping to make it work well.

Usage:
# scale so the 800/600 object will have sides of *at least* 128
>>> scale(800,600,  128,128,  False)
(170, 128)

# scale so the 800/600 object can fit in a box of 128/128
>>> scale(800,600,  128,128,  True)
(128, 96)

# can scale up too
>>> scale(4,3,  900,1600, True)
(900, 675)

>>> scale(4,3,  900,1600, False)
(2133, 1600)

>>> scale(2,8,  1,8,  True)
(1, 4)

2 comments

Pavel Krc 13 years, 2 months ago  # | flag

Sorry, this algorithm isn't guaranteed for a non-square window:

>>> scale(2,8,1,8)
(2, 8)

I think line 4 should be corrected from (nw >= nh) to:

if maximum ^ (nw >= x):
Romain Dartigues (author) 13 years, 2 months ago  # | flag

Thank you Pavel, i noticed this kind of case but somehow forgot to fix it.

Created by Romain Dartigues on Thu, 17 Feb 2011 (MIT)
Python recipes (4591)
Romain Dartigues's recipes (6)

Required Modules

  • (none specified)

Other Information and Tasks