Friday, March 25, 2011

Aspect Ratio came to rescue

In my present assignment I had to deal with large JPEGs (2000px:3000px) images and wanted to store their scaled version (preferably of size 400px:500px).
If we randomly scale an image without considering its Aspect Ratio, the resized image looses clarity very quickly (depends upon how smaller you are trying to make it).

The solution is Aspect Ratio. So, you have the original width and height ratio (2000px:3000px) and need to find out scaled width and height. We need to keep either width or height fix. In my case, I kept the scale width fixed to "400px". Now, if we apply a simple mathematic equation-

width_original : height_original = width_scale : height_scale
height_scale = (width_scale * height_original) / width_original

So, height_scale will be 600px.

Above calculation will determine the scale width and height which will make sure your scaled image is keeping original Aspect Ratio intact and thus you'll get the best quality resized image!

I am using Java ImageIO package to handle Image resizing part. Following is the code snippet (file is the source of the original image)-
final int SCALE_WIDTH = 400;

// Get original Width and Height
int originalWidth = srcImage.getWidth();
int originalHeight = srcImage.getHeight();
// Scale width and height
int newWidth = originalWidth;
int newHeight = 0;

if(newWidth GREATER_THAN SCALE_WIDTH)
newWidth = SCALE_WIDTH;
//Find out scaled Height
newHeight = (newWidth * originalHeight)/originalWidth;
// Save resized image
BufferedImage dest = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_RGB);
Graphics2D g = dest.createGraphics();
AffineTransform at = AffineTransform.getScaleInstance(
(double) newWidth / srcImage.getWidth(),
(double) newHeight / srcImage.getHeight());
g.drawRenderedImage(srcImage, at);
ImageIO.write(dest, format, file);

That's it. Hope it helps.