Scale an image while maintaining aspect ratio without falling below targets

I wonder if anyone can help me with the math / pseudo-code / java code to scale the image to the target dimension. the requirement is to maintain aspect ratio, but not to fall below the target dimension on both x and y scales. The final estimated size may be larger than the requested target, but it should be closest to the target.

Example: I have a 200x100 image. it must be reduced to a target size of 30x10. I need to find the minimum dimension that maintains the aspect ratio of the origin, where x and y of the scale are at least what is indicated in the target. in our example, 20x10 is not good because the x scale has fallen below the target (which is 30). the closest one will be 30x15

Thank.

+5
source share
2 answers
targetRatio = targetWidth / targetHeight;
sourceRatio = sourceWidth / sourceHeight;
if(sourceRatio >= targetRatio){ // source is wider than target in proportion
    requiredWidth = targetWidth;
    requiredHeight = requiredWidth / sourceRatio;      
}else{ // source is higher than target in proportion
    requiredHeight = targetHeight;
    requiredWidth = requiredHeight * sourceRatio;      
} 

So your final image:

  • always placed inside the target but not clipped.

  • keeps the original aspect ratio.

  • and always has either a width or a height (or both) that exactly match the target.

+11
source

, , . , .

Original          Target
200 x 100   ->    30 x 10

1. You take the bigger value of the target dimensions (in our case 30)
2. Check if its smaller than the corresponding original width or height
  2.1 If its smaller define this as the new width (So 30 is the new width)
  2.2 If its not smaller check the other part
3. Now we have to calculate the height which is simply the (30/200)*100

So as result you get like you wrote: 30 x 15

, :)

BufferedImage BufferedImage .

BufferedImage before = getBufferedImage(encoded);
int w = before.getWidth();
int h = before.getHeight();
BufferedImage after = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
AffineTransform at = new AffineTransform();
at.scale(2.0, 2.0); // <-- Here you should use the calculated scale factors
AffineTransformOp scaleOp = 
new AffineTransformOp(at, AffineTransformOp.TYPE_BILINEAR);
after = scaleOp.filter(before, after);
+1

All Articles