Java


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!

JAVA:
  1. package es.gaea.utils;
  2.  
  3. import java.awt.RenderingHints;
  4. import java.awt.geom.AffineTransform;
  5. import java.awt.image.AffineTransformOp;
  6. import java.awt.image.BufferedImage;
  7. import java.io.File;
  8. import java.io.IOException;
  9. import javax.imageio.ImageIO;
  10. import org.apache.log4j.Logger;
  11.  
  12. /** Clase que implementa un procesador para imagenes y juguetear con ellas */
  13. public class ProcesadorImagenes {
  14.  
  15.         /** Logger de la clase */
  16.         private static Logger logger = Logger.getLogger(ProcesadorImagenes.class);
  17.        
  18.         /** Opciones de renderizado para las imagenes */
  19.         private RenderingHints opciones = new RenderingHints(null);
  20.        
  21.         /** Constructor de la clase */
  22.         public ProcesadorImagenes() {
  23.                
  24.                 // Cargo las opciones de renderizado que me apetezcan   
  25.                 opciones.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
  26.                 opciones.put(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
  27.                 opciones.put(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_DISABLE);
  28.                 opciones.put(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
  29.                 opciones.put(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
  30.                 opciones.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
  31.                 opciones.put(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_NORMALIZE);
  32.                 opciones.put(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
  33.         }
  34.        
  35.         /** Devuelve la lista de formatos disponibles a leer por ImageIO       
  36.          * @return un array de strings con los mismos. 
  37.          */
  38.         public String[] dameFormatosUsables(){
  39.        
  40.                 return ImageIO.getReaderFormatNames();
  41.         }
  42.  
  43.  
  44.         /** Calcula el factor de escala minimo y en base a eso
  45.          * escala la imagen segun dicho factor. 
  46.         * @param nMaxWidth maximo tamaño para el ancho
  47.         * @param nMaxHeight nmaximo tamaño para el alto       
  48.         * @param imagen Imagen que vamos a escalar
  49.         * @return Devuelve la imagen escalada para poderla trastocar o null si hay error
  50.         */
  51.         public BufferedImage escalarATamanyo(final BufferedImage imagen,
  52.                         final int maximoAncho, final int maximoAlto) {
  53.  
  54.                 // Comprobacion de parametros
  55.                 if (imagen == null || maximoAlto == 0 || maximoAncho == 0) {
  56.                         return null;
  57.                 }
  58.                
  59.                 // Capturo ancho y alto de la imagen
  60.                 int anchoImagen = imagen.getHeight();
  61.                 int altoImagen = imagen.getWidth();
  62.  
  63.                 // Calculo la relacion entre anchos y altos de la imagen
  64.                 double escalaX = (double)maximoAncho / (double)anchoImagen;
  65.                 double escalaY = (double)maximoAlto / (double)altoImagen;
  66.                
  67.                 // Tomo como referencia el minimo de las escalas
  68.                 double fEscala = Math.min(escalaX, escalaY);
  69.                
  70.                 // Devuelvo el resultado de aplicar esa escala a la imagen
  71.                 return escalar(fEscala, imagen);
  72.         }
  73.  
  74.  
  75.         /** Escala una imagen en porcentaje.
  76.         * @param factorEscala ejemplo: factorEscala=0.6 (escala la imagen al 60%)
  77.         * @param srcImg una imagen BufferedImage
  78.         * @return un BufferedImage escalado
  79.         */
  80.         public BufferedImage escalar(final double factorEscala, final BufferedImage srcImg) {
  81.  
  82.                 // Comprobacion de parametros
  83.                 if (srcImg == null) {
  84.                         return null;
  85.                 }
  86.                
  87.                 // Compruebo escala nula
  88.                 if (factorEscala == 1 ) {
  89.  
  90.                         return srcImg;
  91.                 }
  92.                
  93.                 // La creo con esas opciones
  94.                 AffineTransformOp op = new AffineTransformOp(AffineTransform.getScaleInstance(factorEscala, factorEscala), opciones);
  95.                
  96.                 // Devuelve el resultado de aplicar el filro sobre la imagen
  97.                 return op.filter(srcImg, null);
  98.         }
  99.  
  100.        
  101.         /** Metodo que guarda una imagen en disco
  102.          * @param imagen Imagen a almacenar en disco
  103.          * @param rutaFichero Ruta de la imagen donde vamos a salvar la imagen
  104.          * @param formato Formato de la imagen al almacenarla en disco
  105.          * @return Booleano indicando si se consiguio salvar con exito la imagen
  106.          */
  107.         public boolean salvarImagen(final BufferedImage imagen,
  108.                         final String rutaFichero, final String formato) {
  109.                
  110.                 // Comprobacion de parametros
  111.                 if (imagen != null && rutaFichero != null && formato != null) {
  112.        
  113.                         try {
  114.                                 ImageIO.write( imagen, formato, new File( rutaFichero ));
  115.                                 return true;
  116.                         } catch (Exception e){
  117.                                 // Fallo al guardar
  118.                                 if (logger.isDebugEnabled() == true) {
  119.                                         String CODIGO_MENSAJE_ERROR_GUARDADO_FICHERO =
  120.                                                 "No se pudo guardar correctamente la imagen en " +
  121.                                                 rutaFichero;
  122.                                         logger.debug(CODIGO_MENSAJE_ERROR_GUARDADO_FICHERO);
  123.                                 }
  124.                                 return false;
  125.                         }
  126.                 } else {
  127.                         // Fallo en los parametros
  128.                         return false;
  129.                 }
  130.         }
  131.  
  132.  
  133.         /** Metodo principal de la clase. Usado como prueba
  134.          * @param args Argumentos del metodo
  135.          */
  136.         public static void main(String args[]) {
  137.        
  138.                 // Variables locales
  139.                 BufferedImage imagen;
  140.                
  141.                 try {
  142.                         imagen = ImageIO.read( new File( "prueba.jpg" ) );
  143.                         ProcesadorImagenes pi = new ProcesadorImagenes();
  144.                        
  145.                         // Escalo algunas imagenes como pruebas
  146.                         BufferedImage imagen800_600 = pi.escalarATamanyo(imagen,800, 600);
  147.                         BufferedImage imagenSnap_Shot = pi.escalarATamanyo(imagen,96, 96);
  148.                         BufferedImage imagenMediana = pi.escalarATamanyo(imagen,500, 500);
  149.                        
  150.                         //      Las salvo en disco
  151.                         pi.salvarImagen(imagen800_600,"imagenG.jpg","jpg");
  152.                         pi.salvarImagen(imagenSnap_Shot,"imagenP.jpg","jpg");
  153.                         pi.salvarImagen(imagenSnap_Shot,"imagenE.png","PNG");
  154.                         pi.salvarImagen(imagenMediana,"imagenA.gif","gif");
  155.                        
  156.                         // Extraigo la lista de formatos capaces de leer
  157.                         String[] formatos = pi.dameFormatosUsables();
  158.                        
  159.                         // los voy mostrando
  160.                         for (int i=0; i <formatos.length; i++) {
  161.                                 System.out.println(formatos[i].toString());
  162.                         }
  163.                        
  164.                         // Final del metodo con exito
  165.                         System.exit(0);
  166.                 } catch (IOException e) {
  167.                         e.printStackTrace();
  168.                 }
  169.         }
  170. } 

http://www.asdocs.com/(link petao)

vs.

http://java.sun.com/j2se/1.5.0/docs/api/index.html

Llevo unos cuatro años ya trabajando en proyectos con Java y nunca había tenido que trabajar con la API de imágenes que Sun proporciona. Bueno, pues ahora estoy embarcado en un pequeño proyecto en el cual había que procesar imágenes. Como siempre me pasa, debido a tiempos, prefiero tirar de google y mirar lo que alguien ha andado y defenderme como buenamente puedo, antes que chaparme la API. Craso error. Después de dar vueltas me bajo un código algo obsoleto, para, un día después descubrir la clase ImageIO, disponible a partir de la versión 1.4, mas potente para estos menesteres.

No es una panacea de clase, pero seguro que ayuda a más de un despistado como yo hace un par de días ;)

JAVA:
  1.  
  2. /*
  3. * ImageUtils.java
  4. *
  5. * Created on 20 de julio de 2005, 11:47
  6. * Resizes jpeg image files on your file system.
  7. * Uses the com.sun.image.codec.jpeg package shipped
  8. * by Sun with Java 2 Standard Edition.
  9. *
  10. * @author Randy Belknap
  11. * @revision Alejandro Sánchez Marcos
  12. * se aprovecha la nueva clase ImageIO de 1.4
  13. * y se añaden algunos métodos nuevos
  14. */
  15.  
  16. package com.electroduendes.util.image;
  17.  
  18. import java.awt.geom.AffineTransform;
  19. import java.awt.image.AffineTransformOp;
  20. import java.awt.image.BufferedImage;
  21. import java.io.File;
  22. import javax.imageio.ImageIO;
  23. import org.apache.log4j.Logger;
  24.  
  25. /**
  26. */
  27. public class ImageUtils {
  28.     static Logger logger = Logger.getLogger(ImageUtils.class);
  29.     /*
  30.      * devuelve la lista de formatos disponibles a leer por ImageIO
  31.      * @return un array de strings con los mismos.
  32.      */
  33.     public static String[] getAvailableFormats(){
  34.         return ImageIO.getReaderFormatNames();
  35.     }
  36.    
  37.     /*
  38.      * devuelve una imagen (buffer) en función de la ruta de un archivo
  39.      * mejoras
  40.      * @param la ruta del archivo con su nombre
  41.      * @return BufferedImage la imagen en el buffer
  42.      */
  43.     public static BufferedImage loadBufferedImage(String fileName) {
  44.         BufferedImage image = null;
  45.         try {
  46.             /*FileInputStream fis = new FileInputStream(fileName);JPEGImageDecoder decoder = JPEGCodec.createJPEGDecoder(fis);bi = decoder.decodeAsBufferedImage();fis.close();*/
  47.             // MAS RAPIDO a partir de 1.4
  48.             image = ImageIO.read( new File( fileName ) );
  49.         }
  50.         catch (Exception e) {
  51.             logger.debug("error al intentar leer la imágen");
  52.             return null;
  53.         }
  54.         return image;
  55.        
  56.     }
  57.     /**
  58.      * comprueba que la imágen tiene un mínimo en pixels
  59.      * width y height tienen que tener un tamaño igual o mayor que el pasado
  60.      * como argumento
  61.      *
  62.      * @param w ancho mínimo
  63.      * @param h alto mínimo
  64.      * @return true o false
  65.      *
  66.      */
  67.     public static boolean isGreaterThanMinSize(int w, int h, BufferedImage imgSrc){
  68.         int nHeight = imgSrc.getHeight();
  69.         int nWidth = imgSrc.getWidth();
  70.         if ((nHeight<h ) || (nWidth<w)){
  71.             return false;
  72.         } else {
  73.             return true;
  74.         }
  75.     }
  76.    
  77.     /*
  78.      * calcula el factor de escala mínimo y en base a eso escala la imagen
  79.      * según el dicho factor.
  80.      * @param nMaxWidth minimo tamaño para el ancho
  81.      * @param nMaxHeight minimo tamaño para el alto
  82.      * @param imgSrc la imágen
  83.      */
  84.     public static BufferedImage scaleToSize(int nMaxWidth, int nMaxHeight, BufferedImage imgSrc) {
  85.         int nHeight = imgSrc.getHeight();
  86.         int nWidth = imgSrc.getWidth();
  87.         double scaleX = (double)nMaxWidth / (double)nWidth;
  88.         double scaleY = (double)nMaxHeight / (double)nHeight;
  89.         double fScale = Math.min(scaleX, scaleY);
  90.         return scale(fScale, imgSrc);
  91.     }
  92.    
  93.     /*
  94.      * escala una imagen en porcentaje.
  95.      * @param scale ejemplo: scale=0.6 (escala la imágen al 60%)
  96.      * @param srcImg una imagen BufferedImage
  97.      * @return un BufferedImage escalado
  98.      */
  99.     public static BufferedImage scale(double scale, BufferedImage srcImg) {
  100.         if (scale == 1 ) {
  101.             return srcImg;
  102.         }
  103.         (AffineTransform.getScaleInstance(scale, scale), null);
  104.        
  105.         return op.filter(srcImg, null);
  106.        
  107.     }
  108.    
  109.     public static void saveImageToDisk(BufferedImage bi, String str, String format) {
  110.         if (bi != null && str != null) {
  111.            
  112.             // más rápido con ImageIO
  113.             try {
  114.                 ImageIO.write( bi, format /* formato */, new File( str ) /* destino */ );
  115.             } catch (Exception e){}
  116.         }
  117.     }
  118.    
  119.    
  120.     public static void main(String args[]) {
  121.         if(args.length != 3){usage();}
  122.         System.out.println(args[0]);
  123.         BufferedImage bImg = loadBufferedImage(args[0]);
  124.         System.out.println