Java Bicubic Image Resizing
As usual I want to share the solutions for my coding problems! I’m sure many of you tried to resize images with Java to make thumbnails for example or to fit some images and logos in a game or just to create an animation…
Anyway, while I was working on a project of mine “DPMagnifier” (Display Picture Magnifier), I had to resize images to a fixed size of 96×96 the same way MSN Messenger does. I checked the Java Documentation, and found out that have implemented some Rendering algorithms. The best algorithm to resize a large image into a small one is the Bicubic! So there was some rendering hints like RenderingHints.VALUE_INTERPOLATION_BICUBIC. but too bad, Java people did not implement this resizing algorithm well! I tried it and it was just the same like the Bilinear algorithm. So enough talking about the issue… here’s the solution:
BufferedImage temp = javax.imageio.ImageIO.read(new File(imagefile));
/* determine thumbnail size from WIDTH and HEIGHT */
int thumbWidth = width;
int thumbHeight = height;
int imageWidth = temp.getWidth(null);
int imageHeight = temp.getHeight(null);
int tempWidth;
int tempHeight;
int x = 0;
int y = 0;
if (imageWidth < imageHeight) {
tempWidth = width;
tempHeight = (int)(((double)imageHeight*width)/imageWidth);
y = -(tempHeight - tempWidth)/2;
}
else {
tempHeight = height;
tempWidth = (int)(((double)imageWidth*height)/imageHeight);
x = -(tempWidth - tempHeight)/2;
}
Image temp1 = temp.getScaledInstance(tempWidth, tempHeight, Image.SCALE_SMOOTH);
image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
image.getGraphics().drawImage(temp1, x, y, null);
try {
javax.imageio.ImageIO.write(image, "png", new File("output.png"));
} catch (IOException e) {
e.printStackTrace();
}
If you have a better solution… or maybe you have implemented a better resizing function, write a comment and share it with us!
Cheers…


I am Elie El Khoury, from Lebanon (Byblos), Woopra co-founder & CIO, Web & Software Developer, Designer, Guitarist, Mac user and the worst blogger on earth! 


November 10th, 2006 at 12:05 pm
Thanks - btw the bicubic ‘hint’ should be actually implemented in Java 1.5. However it doesn’t appear to be working. I believe the code below should do a bicubic transform, but it doesn’t.
BufferedImage source, target…;
double scalex = (double) target.getWidth() / source.getWidth();
double scaley = (double) target.getHeight() / source.getHeight();
AffineTransform at = AffineTransform.getScaleInstance(scalex, scaley);
AffineTransformOp affineTransformOp = new AffineTransformOp(at, AffineTransformOp.TYPE_BICUBIC);
affineTransformOp.filter(source, target);
January 7th, 2007 at 6:35 pm
I’ve found this page while I was looking for some information on Google, so this answer arrives a little late… Anyway, I’ve realized that you suffered the same problem which I did weeks ago, when I was developing an image manipulator for the enterprise where I work.
After reading many documents (althought only one gave a good clue to fix it), I came to the conclusion that the Java 2D library doesn’t work well when you down-resize from very distant sizes. Aproximately when the scale proportion is below the 50% of the image size. If you apply a progressive resizing (by steps), you get a nice and smooth result. I made a recursive function and it worked.
March 4th, 2008 at 8:49 am
use this code
where image is BufferedImage object
Graphics2D g2 = (Graphics2D)g;
AffineTransform at = AffineTransform.getScaleInstance(1.5, 1.5);
AffineTransformOp aop = new AffineTransformOp(at, AffineTransformOp.TYPE_BICUBIC);
g2.drawImage(image, aop, 0, 0);
March 4th, 2008 at 8:51 am
Graphics2D g2 = (Graphics2D)g;
AffineTransform at = AffineTransform.getScaleInstance(1.5, 1.5);
AffineTransformOp aop = new AffineTransformOp(at, AffineTransformOp.TYPE_BICUBIC);
g2.drawImage(image, aop, 0, 0);
June 20th, 2008 at 3:33 pm
Hi,
I’ve given the above algorithm to one of our developers
BufferedImage temp = javax.imageio.ImageIO.read(new File(imagefile));
/* determine thumbnail size from WIDTH and HEIGHT */
int thumbWidth = width;
int thumbHeight = height;
int imageWidth = temp.getWidth(null);
int imageHeight = temp.getHeight(null);
int tempWidth;
int tempHeight;
int x = 0;
int y = 0;
if (imageWidth < imageHeight) {
tempWidth = width;
tempHeight = (int)(((double)imageHeight*width)/imageWidth);
y = -(tempHeight - tempWidth)/2;
}
else {
tempHeight = height;
tempWidth = (int)(((double)imageWidth*height)/imageHeight);
x = -(tempWidth - tempHeight)/2;
}
Image temp1 = temp.getScaledInstance(tempWidth, tempHeight, Image.SCALE_SMOOTH);
image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
image.getGraphics().drawImage(temp1, x, y, null);
try {
javax.imageio.ImageIO.write(image, “png”, new File(”output.png”));
} catch (IOException e) {
e.printStackTrace();
}
But he says
but the ImageIO does not recognize a number of images uploaded by the dealer. It seems to have problems with non-standard colour palettes. This is something we saw frequently in production untill we switched to the current method with the toolkit.
November 4th, 2008 at 10:58 pm
Sorry if I sound a bit simplistic but for resizeing images I always use picnik . com works for me
November 5th, 2008 at 1:13 am
@David,
You can always resize images with any software, but some developers need to create softwares like piknic! This is what’s this tip is all about…