How to resize an image in Java ?

I’m not the expert in Java image processing, but a chance given to implement this re-sized feature in user image upload form, which request re-sized the large image to a smaller size with fixed width and height.

Graphics2D is providing the image re-size feature as follows :

BufferedImage resizedImage = new BufferedImage(IMG_WIDTH, IMG_HEIGHT, type);
Graphics2D g = resizedImage.createGraphics();
g.drawImage(originalImage, 0, 0, IMG_WIDTH, IMG_HEIGHT, null);
g.dispose();

According to some articles, if you want to increase the re-sized image quality, you can add the RenderingHints as follows :

BufferedImage resizedImage = new BufferedImage(IMG_WIDTH, IMG_HEIGHT, type);
Graphics2D g = resizedImage.createGraphics();
g.drawImage(originalImage, 0, 0, IMG_WIDTH, IMG_HEIGHT, null);
g.dispose();
g.setComposite(AlphaComposite.Src);
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g.setRenderingHint(RenderingHints.KEY_RENDERING,RenderingHints.VALUE_RENDER_QUALITY);
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);

1. Example

Here is a website snapshot, the following program will re-size this image to a fixed width and height image (100 x 100).

mkyong.jpg (640 x 310) – 46KB

mkyong

2. Source code

ImageTest.java
import java.awt.AlphaComposite;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
 
/*
 * @author mkyong
 *
 */
public class ImageTest {
 
	private static final int IMG_WIDTH = 100;
	private static final int IMG_HEIGHT = 100;
 
	public static void main(String [] args){
 
	try{
 
		BufferedImage originalImage = ImageIO.read(new File("c:\\image\\mkyong.jpg"));
		int type = originalImage.getType() == 0? BufferedImage.TYPE_INT_ARGB : originalImage.getType();
 
		BufferedImage resizeImageJpg = resizeImage(originalImage, type);
		ImageIO.write(resizeImageJpg, "jpg", new File("c:\\image\\mkyong_jpg.jpg")); 
 
		BufferedImage resizeImagePng = resizeImage(originalImage, type);
		ImageIO.write(resizeImagePng, "png", new File("c:\\image\\mkyong_png.jpg")); 
 
		BufferedImage resizeImageHintJpg = resizeImageWithHint(originalImage, type);
		ImageIO.write(resizeImageHintJpg, "jpg", new File("c:\\image\\mkyong_hint_jpg.jpg")); 
 
		BufferedImage resizeImageHintPng = resizeImageWithHint(originalImage, type);
		ImageIO.write(resizeImageHintPng, "png", new File("c:\\image\\mkyong_hint_png.jpg")); 
 
	}catch(IOException e){
		System.out.println(e.getMessage());
	}
 
    }
 
    private static BufferedImage resizeImage(BufferedImage originalImage, int type){
	BufferedImage resizedImage = new BufferedImage(IMG_WIDTH, IMG_HEIGHT, type);
	Graphics2D g = resizedImage.createGraphics();
	g.drawImage(originalImage, 0, 0, IMG_WIDTH, IMG_HEIGHT, null);
	g.dispose();
 
	return resizedImage;
    }
 
    private static BufferedImage resizeImageWithHint(BufferedImage originalImage, int type){
 
	BufferedImage resizedImage = new BufferedImage(IMG_WIDTH, IMG_HEIGHT, type);
	Graphics2D g = resizedImage.createGraphics();
	g.drawImage(originalImage, 0, 0, IMG_WIDTH, IMG_HEIGHT, null);
	g.dispose();	
	g.setComposite(AlphaComposite.Src);
 
	g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
	RenderingHints.VALUE_INTERPOLATION_BILINEAR);
	g.setRenderingHint(RenderingHints.KEY_RENDERING,
	RenderingHints.VALUE_RENDER_QUALITY);
	g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
	RenderingHints.VALUE_ANTIALIAS_ON);
 
	return resizedImage;
    }	
}

See result :

JPG (4KB)PNG (9KB)JPG + Hints (4KB)PNG + Hints (9KB)
mkyong_jpgmkyong_pngmkyong_hint_jpgmkyong_hint_png

Conclusion

As you see the re-sized image , the file size of the re-sized PNG image is larger than the re-sized JPEG image, but the PNG quality is better than JPG after re-sized. The hints will not take any effect in JPG format, however i didn’t see any difference between PNG and PNG + hints either, even someone told about adding the rendering hints will increase the image quality?

P.S Please share Java image tips if you know some :)

References

  1. http://java.sun.com/j2se/1.4.2/docs/api/javax/imageio/ImageIO.html
  2. http://java.sun.com/j2se/1.4.2/docs/api/java/awt/image/BufferedImage.html
  3. http://java.sun.com/j2se/1.5.0/docs/api/java/awt/Graphics2D.html
  4. http://today.java.net/pub/a/today/2007/04/03/perils-of-image-getscaledinstance.html
  5. http://www.servletsuite.com/servlets/imagescale.htm
  6. http://www.componenthouse.com/article-20
Tags :

About the Author

mkyong
Founder of Mkyong.com and HostingCompass.com, love Java and open source stuff. Follow him on Twitter, or befriend him on Facebook or Google Plus. If you like my tutorials, consider make a donation to these charities.

Comments

  • momy

    ??GIF?JPG?????????????

    ?????

    public static void reduceImg(String imgsrc, String imgdist, int widthdist,
    int heightdist) {
    try {
    File srcfile = new File(imgsrc);
    if (!srcfile.exists()) {
    return;
    }
    Image src = javax.imageio.ImageIO.read(srcfile);

    BufferedImage tag= new BufferedImage((int) widthdist, (int) heightdist,
    BufferedImage.TYPE_INT_RGB);

    tag.getGraphics().drawImage(src.getScaledInstance(widthdist, heightdist, Image.SCALE_SMOOTH), 0, 0, null);
    /// tag.getGraphics().drawImage(src.getScaledInstance(widthdist, heightdist, Image.SCALE_AREA_AVERAGING), 0, 0, null);

    FileOutputStream out = new FileOutputStream(imgdist);
    JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
    encoder.encode(tag);
    out.close();

    } catch (IOException ex) {
    ex.printStackTrace();
    }
    }

    • Ivan E.

      He utilizado el código, pero he cambiado algunas líneas.

      public static void reduceImg(String imgsrc, String imgdist,String type, int widthdist,
      int heightdist) {
      try {
      File srcfile = new File(imgsrc);
      if (!srcfile.exists()) {
      return;
      }
      Image src = javax.imageio.ImageIO.read(srcfile);

      BufferedImage tag= new BufferedImage((int) widthdist, (int) heightdist,
      BufferedImage.TYPE_INT_RGB);

      tag.getGraphics().drawImage(src.getScaledInstance(widthdist, heightdist, Image.SCALE_SMOOTH), 0, 0, null);
      // tag.getGraphics().drawImage(src.getScaledInstance(widthdist, heightdist, Image.SCALE_AREA_AVERAGING), 0, 0, null);

      FileOutputStream out = new FileOutputStream(imgdist);
      ImageIO.write(tag, type, out);
      out.close();

      } catch (IOException ex) {
      ex.printStackTrace();
      }
      }

  • http://- Fatih

    Thanks

  • nayef

    after drawing and disposing the graphics, rendering hints were set. shouldn’t the rendering hins be set before drawing?

  • http://www.javatheprogram.blogspt.com Dara

    That is good. I wrote may programs inclusing image resize to manipulate image. You can check them at http://www.javatheprogram.blogspot.com

  • http://www.skillshared.blogspot.com Semika

    Thank you so much.

  • http://www.journaldev.com Pankaj

    Actually using RenderingHints do affect the output image quality and size. I have written a similar program and played with it for sometime to check it out. In your case the image is of website and quality is not too good to recognize the difference from naked eye. Check it out here:

    http://www.journaldev.com/615/java-image-resize-program-using-graphics2d-example

  • Abdul Rehman

    Hi!

    I have an implementation to resize an image with rendering hints and converting it to TYPE_BYTE_GRAY. Code works fine until i get an original image having type of TYPE_BYTE_BINARY. Let’s say if i do not convert it to TYPE_BYTE_GRAY but only want to resize it. How am i gonna do that? I have tried it against drawImage(img, 0, 0, null) and drawImage(img, 0, 0, newWidth, newHeight, null) but was not successful. In first case the image gets cropped and in second case it throws exception. So what i want to ask is, Is there any way to resize TYPE_BYTE_BINARY image to customized width and height? Thank you

  • Anand Singh

    its giving exceptin

    java.lang.IllegalArgumentException: Can’t load standard profile: sRGB.pf

  • http://www.loocsij.com Bruce Wen
    	public static BufferedImage resizeImage(BufferedImage image, int longer, int width,
    			int height, boolean isWithHint) {
    		int oldWidth = image.getWidth();
    		int oldHeight = image.getHeight();
     
    		boolean isWidthLonger = oldWidth > oldHeight;
     
    		int newWidth = -1;
    		int newHeight = -1;
     
    		if (longer > 0) {
    			if (isWidthLonger) {
    				newWidth = longer;
    				newHeight = NumberUtil.convert(new double[] { longer
    						* ((double) oldHeight / (double) oldWidth) })[0]
    						.intValue();
    			} else {
    				newHeight = longer;
    				newWidth = NumberUtil.convert(new double[] { longer
    						* ((double) oldWidth / (double) oldHeight) })[0]
    						.intValue();
    			}
    		} else {
    			newWidth = width;
    			newHeight = height;
    		}
     
    		int type = image.getType() == 0? BufferedImage.TYPE_INT_ARGB : image.getType();
     
    		return isWithHint ? resizeImageWithHint(image, type,
    				newWidth, newHeight) : resizeImageWithoutHint(image,
    						type, newWidth, newHeight);
    	}
  • Pingback: Java resize | Greenlivingand()

  • Arjun

    Thanks a ton, was stuck on this topic for days before i found your post.
    Keep up the good work..

    Arjun

  • http://peliculasrapido.blogspot.com.ar/ Claudio

    grooooooooooosooooooooooooooooooooo me solucionaste la vida chabonnnnn!!!

  • Jiten K

    Great example!!! thanks Mkyong!!! You are great!!!

  • http://javasrilankansupport.blogspot.com JSupport

    Check out this

    How to Resize Image according to the screen size using Java

    How to resize an image in Java

  • Misgana

    Nice short and precise.Thanks a lot.

  • Nghia Nguyen

    Great example!!!

  • Spidey

    This made my Icons lose their transparency, any idea why?

  • Hugo Garcia-Cotte

    There is a little error in your code, the rendering hints have to be given before you use the drawImage method on g.
    And then you can see the rendering is better.

    • lolka

      +1

      or this is some trick, but i suppose rendering hits must be set BEFORE drawing an image

  • http://tikona.in Ram

    Hi Dude,

    Very nice Example for Sacling the buffred Image …

    Thanks ,

    Ram

  • noha mohamed

    it is a good work .. :)

  • http://olcayertas.wordpress.com Olcay Erta?

    Thank you very much. It was really helpful.

  • Pingback: Resim Boyutlama / Image Resizing()

  • http://fheufeifefhii.com Linda Hernandez

    This is the really good and perfect discussion as well with no doubt this is the best approach.

  • http://www.pincody.com Alkhawar

    Thanks Dear for posting such a nice post.

  • http://code.google.com/p/java-image-scaling/ Morten Nobel-Jørgensen

    You should also consider using java-image-scaling library, this gives a better and faster implementation of image scaling:

    http://code.google.com/p/java-image-scaling/

    – Morten

    • http://www.mkyong.com mkyong

      Thanks for sharing, will play around with it.

  • mkyong

    Thanks for the contribution, really appreciated it.

  • Dan Smith
  • Daniel Manzke

    Hi,

    I think you have set the Hints before drawing, so they will be recognized and you should use the method for g.addHints(..), so you can give them all. In your way I think you will be overwritten every time using the set-Method.

    Last but not least you should add some kind of calculation for the image size, because often your picture won’t be 100×100. Often they will be something like 100×67 or so.
    So you could calculate which is the greatest length, scale that down to your size you want to have and then use this scale factor to calculate the other length.

    Hope this helps a little bit. If you write me an email. ;)

    Bye,
    Daniel