electroduendes.com

bitácora de un desarrollador interactivo

electroduendes.com header image 2

Procesado de imágenes en Java II

July 24th, 2007 · 6 Comments

Javier Murillo me manda una mejora para la clase ImageUtils que publiqué en la entrada procesado de imágenes en Java. Es una alegría saber que otros desarrolladores trabajen con el código que publico, y que, como en este caso, se interesan por mejorarlo y reenviarlo. Gracias Javier!

package es.gaea.utils;
 
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import org.apache.log4j.Logger;
 
/** Clase que implementa un procesador para imagenes y juguetear con ellas */
public class ProcesadorImagenes {
 
	/** Logger de la clase */
	private static Logger logger = Logger.getLogger(ProcesadorImagenes.class);
 
	/** Opciones de renderizado para las imagenes */ 
	private RenderingHints opciones = new RenderingHints(null);
 
	/** Constructor de la clase */
	public ProcesadorImagenes() {
 
		// Cargo las opciones de renderizado que me apetezcan	
		opciones.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
		opciones.put(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
		opciones.put(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_DISABLE);
		opciones.put(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
		opciones.put(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
		opciones.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
		opciones.put(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_NORMALIZE);
		opciones.put(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
	}
 
	/** Devuelve la lista de formatos disponibles a leer por ImageIO	
	 * @return un array de strings con los mismos.	
	 */
	public String[] dameFormatosUsables(){
 
		return ImageIO.getReaderFormatNames();
	}
 
 
	/** Calcula el factor de escala minimo y en base a eso 
	 * escala la imagen segun dicho factor.	
	* @param nMaxWidth maximo tamaño para el ancho
	* @param nMaxHeight nmaximo tamaño para el alto	
	* @param imagen Imagen que vamos a escalar
	* @return Devuelve la imagen escalada para poderla trastocar o null si hay error
	*/
	public BufferedImage escalarATamanyo(final BufferedImage imagen,
			final int maximoAncho, final int maximoAlto) {
 
		// Comprobacion de parametros
		if (imagen == null || maximoAlto == 0 || maximoAncho == 0) {
			return null;
		}
 
		// Capturo ancho y alto de la imagen 
		int anchoImagen = imagen.getHeight();
		int altoImagen = imagen.getWidth();
 
		// Calculo la relacion entre anchos y altos de la imagen
		double escalaX = (double)maximoAncho / (double)anchoImagen;
		double escalaY = (double)maximoAlto / (double)altoImagen;
 
		// Tomo como referencia el minimo de las escalas
		double fEscala = Math.min(escalaX, escalaY);
 
		// Devuelvo el resultado de aplicar esa escala a la imagen
		return escalar(fEscala, imagen);
	}
 
 
	/** Escala una imagen en porcentaje.
	* @param factorEscala ejemplo: factorEscala=0.6 (escala la imagen al 60%)
	* @param srcImg una imagen BufferedImage
	* @return un BufferedImage escalado
	*/
	public BufferedImage escalar(final double factorEscala, final BufferedImage srcImg) {
 
		// Comprobacion de parametros
		if (srcImg == null) {
			return null;
		}
 
		// Compruebo escala nula
		if (factorEscala == 1 ) {
 
			return srcImg;
		}
 
		// La creo con esas opciones
		AffineTransformOp op = new AffineTransformOp(AffineTransform.getScaleInstance(factorEscala, factorEscala), opciones);
 
		// Devuelve el resultado de aplicar el filro sobre la imagen
		return op.filter(srcImg, null);
	}
 
 
	/** Metodo que guarda una imagen en disco 
	 * @param imagen Imagen a almacenar en disco
	 * @param rutaFichero Ruta de la imagen donde vamos a salvar la imagen
	 * @param formato Formato de la imagen al almacenarla en disco
	 * @return Booleano indicando si se consiguio salvar con exito la imagen
	 */
	public boolean salvarImagen(final BufferedImage imagen, 
			final String rutaFichero, final String formato) {
 
		// Comprobacion de parametros
		if (imagen != null && rutaFichero != null && formato != null) {
 
			try {
				ImageIO.write( imagen, formato, new File( rutaFichero ));
				return true;
			} catch (Exception e){
				// Fallo al guardar
				if (logger.isDebugEnabled() == true) {
					String CODIGO_MENSAJE_ERROR_GUARDADO_FICHERO = 
						"No se pudo guardar correctamente la imagen en " + 
						rutaFichero;
					logger.debug(CODIGO_MENSAJE_ERROR_GUARDADO_FICHERO);
				}
				return false;
			}
		} else {
			// Fallo en los parametros 
			return false;
		}
	}
 
 
	/** Metodo principal de la clase. Usado como prueba
	 * @param args Argumentos del metodo
	 */
	public static void main(String args[]) {
 
		// Variables locales
		BufferedImage imagen;
 
		try {
			imagen = ImageIO.read( new File( "prueba.jpg" ) );
			ProcesadorImagenes pi = new ProcesadorImagenes();
 
			// Escalo algunas imagenes como pruebas
			BufferedImage imagen800_600 = pi.escalarATamanyo(imagen,800, 600);
			BufferedImage imagenSnap_Shot = pi.escalarATamanyo(imagen,96, 96);
			BufferedImage imagenMediana = pi.escalarATamanyo(imagen,500, 500);
 
			//	Las salvo en disco
			pi.salvarImagen(imagen800_600,"imagenG.jpg","jpg");
			pi.salvarImagen(imagenSnap_Shot,"imagenP.jpg","jpg");
			pi.salvarImagen(imagenSnap_Shot,"imagenE.png","PNG");
			pi.salvarImagen(imagenMediana,"imagenA.gif","gif");
 
			// Extraigo la lista de formatos capaces de leer
			String[] formatos = pi.dameFormatosUsables();
 
			// los voy mostrando
			for (int i=0; i < formatos.length; i++) {
				System.out.println(formatos[i].toString());
			}
 
			// Final del metodo con exito
			System.exit(0);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

Tags: Java

6 responses so far ↓

  • 1 Cenit // Aug 3, 2007 at 9:50 am

    Me ha sido de mucha ayuda. Gracias!

  • 2 seba // Sep 26, 2007 at 4:25 pm

    Como estas alex. Queria agradercete por estas publicaciones sobre manipulación de imagenes en Java, me han sido muy útiles.
    Actualmente estoy trabajando con una aplicación que tiene que levantar imagenes .tif y debe permitir hacer zoom sobre ella. He tenido algunos problemas en cuanto a la velocidad de pintado del componente: tarda mucho (entre 1 y 1,5 segundos aprox) en refrescar la imagen en pantalla. Una solución es crear una imagen .jpg y mostrar esta última, esto hace que el repintado de la imagen sea casi instantaneo, pero por otro lado tengo que trabajar con 3 copias de la imagen en memoria (la .tif, la .jpg y una copia de la .jpg a la que le realizo algunas transformaciones) y la aplicación se me va a 45MB aproximadamente de memoria cuando esta en ejecución. ¿Alguna sugerencia? Desde ya muchas gracias.

  • 3 Javier Murillo // Feb 29, 2008 at 7:12 pm

    Buenas Alex,

    Al respecto de esta clase le he dado una nueva vuelta de tuerca para un proyecto que tenía entre manos. La he vuelto a colgar por si a alguien le es de utilidad en algún proyecto.

    URL:

    http://jamurblan.wordpress.com/2008/02/27/un-poco-de-thumbnails-en-java/

  • 4 Javier Murillo // Feb 29, 2008 at 7:14 pm

    Por cierto, me gusta más el diseño de tu blog profesional :) ) xDD.

  • 5 David // Nov 17, 2008 at 2:51 am

    Hola, buenas tardes. es que necesito saber como ingreso una imagen en una ventana, utilizando netbeans, lo siento tal vez es algo muy sencillo pero me urge saber como por favor si me pueden contestar lo anstesp osible lo agradeceria muucho espero su respuesta por favor. david_onesimo@hotmail.com gracias

  • 6 carlos // Mar 26, 2009 at 10:57 pm

    bueno dia. como hago para girar una imagen . la coso es un juego tipo tower defense que quiero hacer, pero no consigo hacer hicar el cañon de los atacantes para q apunten a los enemigos si me puedes ayudar, estoy trabajando en netbeans java. y soy nuevo en esto,

Leave a Comment