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...

7 Responses to “Java Bicubic Image Resizing”

  1. Danack says:

    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);

    • pcs says:

      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);

  2. Negora says:

    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.

  3. pcs says:

    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);

  4. whe says:

    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.

  5. Sorry if I sound a bit simplistic but for resizeing images I always use picnik . com works for me

  6. Elie says:

    @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…

Leave a Reply