Search code examples
javaimageresizegraphics2dsmoothing

Java Graphics2D interpolation doesn't seem to work on resized images


I want to resize an image to a smaller size suitable for thumbnail and export it. The problem is that the result image looks really bad with a lot of visible aliasing as if it's using really simple algorithm.

I've read many articles about this that suggest using rendering hints to enable quality rendering and bicubic interpolation but they don't seem to affect anything, it's like they just don't apply to the final image. I also tried anti aliasing hints (which didn't work too) but I guess they are for drawing.

For the sake of simplicity I'll show only the code that does the resizing and writing and I'll put hardcoded dimensions for the result image.

    final BufferedImage imageOriginal = ImageIO.read(new File("/some-path/arch3.jpg"));
int newWidth = 267, newHeight = 400;
    BufferedImage imageResized = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_RGB);
    Graphics2D g2d = (Graphics2D) imageResized.getGraphics();
    g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
    g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
    g2d.drawImage(imageOriginal, 0, 0, imageResized.getWidth(), imageResized.getHeight(), 0, 0, imageOriginal.getWidth(), imageOriginal.getHeight(), null);

     try {
         ImageIO.write(imageResized, "jpg", new File("/some-path/arch3_converted.jpg"));
     } catch (Exception ioException) {
       System.out.println(ioException.toString());
     } 

This is the original image: https://drive.google.com/open?id=1qsZFQWWneBlHAahV2s5CwlxlCYvnHiU8 (4480×6720) This is the converted result: https://drive.google.com/open?id=1WEcYb7QRlurOK-_dHr_BAk1HrLxPkdIl (267x400) As you can see in the result (especially on the lines) it doesn't seem right.


Solution

  • use "image.getScaledInstance"

     String imgOriginalPath= "arch3.jpg";          
     String imgTargetPath= "arch3_resize.jpg"; 
     String imgFormat = "jpg";                          
     int newWidth = 200;                                  
     int newHeight = 300;                                 
    
     try{
        Image image = ImageIO.read(new File(imgOriginalPath));
        Image resizeImage = image.getScaledInstance(newWidth, newHeight, Image.SCALE_SMOOTH);
        BufferedImage newImage = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_RGB);
        Graphics g = newImage.getGraphics();
        g.drawImage(resizeImage, 0, 0, null);
        g.dispose();
        ImageIO.write(newImage, imgFormat, new File(imgTargetPath));
     }catch (Exception e){e.printStackTrace();}
    

    I test it, and it was great. i hope u like it too. :)