scale an image keeping the aspect ratio without falling below the targets
I wonder if anybody can help me with the math/pseudo code/java code to scale an image to a target dimension. the requirement is to keep the aspect ratio, but not falling below the target dimension on both x and y scales. the final calculated dimension can be greater than the requested target but it needs to be the the closest one to the target.
example: I have an image that is 200x100. it needs to be scaled down to a target dimension 30x10. i need to find the minimal dimension that keeps the aspect ratio of the origin where both x and y scales are at least what is specifie开发者_如何学Pythond in the target. in our example, 20x10 is not good because the x scale fell below the target (which is 30). the closest one would be 30x15
Thank you.
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;
}
This way your final image :
always fits inside the target whereas not being cropped.
keeps its original aspect ratio.
and always has either the width or height (or both) exactly matching the target's.
Well in your example you kind off already used the algorithm you're looking for. I will use the example you have given.
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
Hope this was clear :)
In the coding part you could use the BufferedImage and simply create a new BufferedImage with the correct scale value like that.
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);
精彩评论