views:

417

answers:

2

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!

+1  A: 

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
Mark Ransom
Only the X (width) is under constraints of resizing. The other Y (height) is cropping.
Suroot
That constraint wasn't stated, nor was it evident from your examples. In that case, use scale=maxwidth/oldwidth instead and remove the cropleft/cropright calculations, the rest remains the same.
Mark Ransom
+1  A: 

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;
}
Suroot