ImageResizer.java 3.79 KB
package it.softecspa.fileproxy.util;

import it.softecspa.fileproxy.services.common.ManagerException;
import it.softecspa.kahuna.io.File;

import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Transparency;
import java.awt.image.BufferedImage;
import java.io.IOException;

import javax.imageio.ImageIO;

public class ImageResizer {

	
	private File source; 
	private BufferedImage original;
	private int type;
	
	private BufferedImage modified;
	
	
	public ImageResizer(String source) {
		this.source = new File(source);
	}
	
	public ImageResizer(java.io.File source) {
		if (source instanceof File) {
			this.source = (File)source;
			return;
		}
		this.source = new File(source);
	}
	
	
	
	public void read() throws ManagerException {
		try {
			original = ImageIO.read(source);
		} catch (IOException e) {
			throw new ManagerException("IOException reading file '"+source.getAbsolutePath()+"'", e);
		}
		
		//type = (original.getType()==0?BufferedImage.TYPE_INT_ARGB:original.getType());
		type = (original.getTransparency() == Transparency.OPAQUE) ? BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB;

	}
	
	
	public BufferedImage getOriginal() {
		return original;
	}

	
	public int getType() {
		return type;
	}
	
	public void resize(int width, int height) {
		this.modified = resizeImage(original, type, width, height);
	}
	
	public void resizeWithHint(int width, int height, boolean higherQuality) {
		this.modified = resizeImageWithHints(original, type, width, height, higherQuality);
	}
	
	
	public void overwrite() throws ManagerException {
		write(source);
	}
	
	
	public void write(java.io.File target) throws ManagerException {
		File newfile = (target instanceof File)?new File(target):(File)target;
		try {
			ImageIO.write(modified, newfile.getExtension(), newfile);
		} catch (IOException e) {
			throw new ManagerException("Error writing file '"+newfile.getAbsolutePath()+"'");			
		}	
	}
	
	
	
	private BufferedImage resizeImage(BufferedImage originalImage, int type, int width, int height) {
		BufferedImage resizedImage = new BufferedImage(width, height, type);
		
		Graphics2D g = resizedImage.createGraphics();
		g.drawImage(originalImage, 0, 0, width, height, null);
		g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
		g.dispose();

		return resizedImage;
	}
	
	
	private BufferedImage resizeImageWithHints(BufferedImage originalImage, int type, int targetWidth, int targetHeight, boolean higherQuality) {
		
		// Vedi http://today.java.net/pub/a/today/2007/04/03/perils-of-image-getscaledinstance.html
		
		BufferedImage resizedImage = (BufferedImage) originalImage;
		
		int w, h;
		if (higherQuality) {
			// Use multi-step technique: start with original size, then
			// scale down in multiple passes with drawImage()
			// until the target size is reached
			w = originalImage.getWidth();
			h = originalImage.getHeight();
		} else {
			// Use one-step technique: scale directly from original
			// size to target size with a single drawImage() call
			w = targetWidth;
			h = targetHeight;
		}

		do {
			if (higherQuality && w > targetWidth) {
				w /= 2;
				if (w < targetWidth) {
					w = targetWidth;
				}
			}

			if (higherQuality && h > targetHeight) {
				h /= 2;
				if (h < targetHeight) {
					h = targetHeight;
				}
			}

			BufferedImage tmp = new BufferedImage(w, h, type);
			Graphics2D g2 = tmp.createGraphics();
			g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
			g2.drawImage(resizedImage, 0, 0, w, h, null);
			g2.dispose();

			resizedImage = tmp;
			
		} while (w != targetWidth || h != targetHeight);

		return resizedImage;
		
	}
	
		
	
}