How to "smart resize" a displayed image to original aspect ratio

Here's a solution I came up with when having to deal with this problem. Turned out pretty short and straightforward imo, just wanted to share it.

Handy "formulas": ratio = W / H W = H * ratio H = W / ratio

  1. Calculate the ratio.
  2. Calculate the height of the image if you would set the width to the new size width (maximum allowed width).
  3. Calculate the width of the image if you would set the height to the new size height (maximum allowed height).
  4. See which of the two sizes does not override the max size in any dimension. If the ratio is not 1 one of them will always be wrong and one will always be correct.

In Javascript

// Returns array with new width and height
function proportionalScale(originalSize, newSize)
{
    var ratio = originalSize[0] / originalSize[1];

    var maximizedToWidth = [newSize[0], newSize[0] / ratio];
    var maximizedToHeight = [newSize[1] * ratio, newSize[1]];

    if (maximizedToWidth[1] > newSize[1]) { return maximizedToHeight; }
    else { return maximizedToWidth; }
}

originalSize and newSize is an array [0] = width, [1] = height


If I'm interpreting your spec correctly, you want a result that is no larger than the one the end-user laid out originally; you want one of the two dimensions to shrink, and the other to stay the same. In other words, the new size should fill the designer space in one direction while shortening the size in the other direction to retain the original aspect ratio.

original_ratio = original_width / original_height
designer_ratio = designer_width / designer_height
if original_ratio > designer_ratio
    designer_height = designer_width / original_ratio
else
    designer_width = designer_height * original_ratio

Often you'll be working with integer coordinates, but the divisions to produce the ratios above need to be floating point. Here's a rearrangement of the formula to be more integer friendly. Make sure your integers have the range to handle the maximum width*height.

if original_width * designer_height > designer_width * original_height
    designer_height = (designer_width * original_height) / original_width
else
    designer_width = (designer_height * original_width) / original_height