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("com.sun.media.jai.disableMediaLib", "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( ImageIO.read(f), 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,
        RenderingHints.VALUE_RENDER_QUALITY);	    

    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();
    encoderOutputStream.close();

    //free resources
    seekableImageStream.close();
    resizedImage.dispose();
    originalImage.dispose();

    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);
				fos.write(image);
				fos.close();
			} catch (Exception e) {

			} finally {
				if(fos != null)
					fos.close();
			}
		}
	}

	public void write(String format, HttpServletResponse response) throws IOException  {
		if(image != null) {
			//prepare header to output image
			response.setContentType("image/jpeg");
			response.setStatus(200);	//set status 200, we found an image
			response.getOutputStream().write(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. Ajax/Javascript, HTML5, Android, iPhone/iPad, JAVA, PHP, Cold Fusion, SQL, Air, Flash, Open source software, Frameworks

More Posts

Follow Me:

 

One Response to Resize images with Java: JAI (Java Advanced Imaging) method

  1. Megha Saxena says:

    I really like that you are giving information on core and advance java concepts. Being enrolled at http://www.wiziq.com/course/1779-core-and-advance-java-concepts I found your information very helpful indeed.thanks for it.

Leave a Reply