Here is my second solution on how to resize images with Java. This method is also simple and I think from my experience produces a better quality images from the start. Also has no memory leak in Tomcat 6 comapring to java2d method.

The Java Advanced Imaging API (JAI) provides a set of object-oriented interfaces that supports a simple, high-level programming model which allows images to be manipulated easily in Java applications and applets. JAI goes beyond the functionality of traditional imaging APIs to provide a high-performance, platform-independent, extensible image processing framework.

 * ImageResizerJAI
 * Usage: 
 * 	ImageResizer2D im = new ImageResizer2D(); //init 
 * 	im.resize(Mixed image, int width, int height); //resize image
 * 	@image - BufferedImage - source of the image to resize 
 * 	@image - byte[] - source of the image to resize
 * 	@image - String - path to the image
 * 	@image - File
 * 	@width - int - target width, pass 0 to resize by height  
 * 	@height - int - target height, pass 0 to resize by width only
 *  im.write(String fileDestination, String format); 			//write resized version of the file to drive
 *	im.write(File fileDestination, String format); 				//format how the file should be handled (jpg, gif, png)
 *  im.write(String format, HttpServletResponse response);//flushed resized version of the file to screen

public class ImageResizerJAI {

	private byte[] image;
	public ImageResizerJAI() {
		System.setProperty("", "true");
	public byte[] resize(String img, int targetWidth, int targetHeight) throws IOException {
		return resize(new File(img), targetWidth, targetHeight);
	public byte[] resize(File f, int targetWidth, int targetHeight) throws IOException {		
		return resize(, targetWidth, targetHeight);		
	public byte[] resize(BufferedImage img, int targetWidth, int targetHeight) throws IOException {
		//convert BufferedImage to ByteArray
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		ImageIO.write(img, "jpeg", baos);		
		return resize( baos.toByteArray(), targetWidth, targetHeight);	
	public byte[] resize(byte[] img, int targetWidth, int targetHeight) throws IOException {
		InputStream imageInputStream = new ByteArrayInputStream(img);
    // read in the original image from an input stream
    SeekableStream seekableImageStream = SeekableStream.wrapInputStream(imageInputStream, true);
    RenderedOp originalImage = JAI.create("stream", seekableImageStream);
    ((OpImage) originalImage.getRendering()).setTileCache(null);
    double scale = getImageScale(originalImage.getWidth(), originalImage.getHeight(), targetWidth, targetHeight);
    ParameterBlock paramBlock = new ParameterBlock();
    paramBlock.addSource(originalImage); // The source image
    paramBlock.add(scale); // The xScale
    paramBlock.add(scale); // The yScale
    paramBlock.add(0.0); // The x translation
    paramBlock.add(0.0); // The y translation
    RenderingHints qualityHints = new RenderingHints(RenderingHints.KEY_RENDERING,
    RenderedOp resizedImage = JAI.create("SubsampleAverage", paramBlock, qualityHints);
    // lastly, write the newly-resized image to an output stream, in a specific encoding
    ByteArrayOutputStream encoderOutputStream = new ByteArrayOutputStream();
    JAI.create("encode", resizedImage, encoderOutputStream, "JPEG", null);
    // Export to Byte Array
    image = encoderOutputStream.toByteArray();

    //free resources
    return image;
	public void write(String img, String format) throws IOException {
		write(new File(img), format);

	public void write(File f, String format) throws IOException {		
		FileOutputStream fos = null;
		if(image != null) {
			new File(f.getParent()).mkdirs();	
			try {
				fos = new FileOutputStream(f);
			} catch (Exception e) {
			} finally {
				if(fos != null)
	public void write(String format, HttpServletResponse response) throws IOException  {
		if(image != null) {
			//prepare header to output image
			response.setStatus(200);	//set status 200, we found an image			

	private double getImageScale(int sourceWidth, int sourceHeight,
			int targetWidth, int targetHeight) {
		double scalex = (double) targetWidth / sourceWidth;
		double scaley = (double) targetHeight / sourceHeight;
		return Math.max(scalex, scaley);


Dima Svirid

Software architect, JAVA, Spring, Hibernate, AngularJs, Backbone, MongoDB, Oracle. CTO and Co-Founder of

More Posts

Follow Me: