Question

For instance, if I need to fill a bounding box that is 100px wide by 50px tall, the following input images would have the following behavior:

  1. 200w x 200h gets scaled down 50% and 25% gets chopped off the top and bottom.

  2. 200w x 100h gets scaled down 50% with no cropping.

  3. 100w x 200h gets is not scaled, but 75px get chopped off top and bottom.

This seems like it'd be a common resizing function, but I haven't been able to track down an example of the algorithm.

Will accept answer in any language including pseudo code. A link to a page with the answer is great too!

Was it helpful?

Solution

What you're asking for is pretty easy. Calculate the different scaling factors for the width and the height, then pick the larger one for your actual scale factor. Multiply your input size by the scale, and crop whichever one comes out too large.

scale = max(maxwidth/oldwidth, maxheight/oldheight)
scaledwidth = oldwidth * scale
scaledheight = oldheight * scale
if scaledheight > maxheight:
    croptop = (scaledheight - maxheight) / 2
    cropbottom = (scaledheight - maxheight) - croptop
if scaledwidth > maxwidth:
    cropleft = (scaledwidth - maxwidth) / 2
    cropright = (scaledwidth - maxwidth) - cropleft

OTHER TIPS

Here we make sure that we only scale if X is greater than 100%; then after we've done that, we ensure that we are only 50 px on our Y. If we're greater than 50, then we take the difference and divide by 2 to get the amount removed from the top/bottom.

double percent_x = 1.0;

if(X > 100) {
 percent_x = (float)100/X;
 X *= percent_x;
 Y *= percent_x;
}

int diff_y;
int top_cut, bott_cut;
if( Y > 50 ) {
 diff_y = (Y - 50) / 2;
 top_cut = bott_cut = diff_y;
}

Largely inspired by Mark Ransom's answer (thank you so much - you saved me). For anyone who would like to do this without cropping the image (just fit within the bounds), I've found that this works:

if (maxWidth > width && maxHeight > height) {
  return { width, height };
}

aspectRatio = width / height,
scale       = max(maxWidth / width, maxHeight / height);

scaledHeight = height * scale,
scaledWidth  = width * scale;

if (scaledHeight > maxHeight) {
  scaledHeight = maxHeight;
  scaledWidth  = aspectRatio * scaledHeight;
} else if (scaledWidth > maxWidth) {
  scaledWidth  = maxWidth;
  scaledHeight = scaledWidth / aspectRatio;
}

return { scaledHeight, scaledWidth };
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top