Implementando OperadorRGB2IHSAplicacion

Operador

Ya nos encontramos en situación de empezar a implementar la clase OperadorRGB2IHSAplicacion. Pero antes de implementar esta clase, implementaremos la clase OperadorRGB2IHS.java, que contendrá el operador independiente a la aplicación, y que pretende hacer más fácil su reutilización en caso de ser necesario. Esta práctica de programación se recomienda en Buenas prácticas de programación.

A continuación, adjuntamos el código utilizado para esta operación.

OperadorRGB2IHS.java
package com.coolimagingproject.coloroperations.operador;

import com.coolimagingproject.coolimaging.libreriaimagenes.imagen.publico.Imagen;
import java.awt.Dimension;
import java.awt.image.ComponentColorModel;
import java.awt.image.RenderedImage;
import java.awt.image.renderable.ParameterBlock;

import javax.media.jai.IHSColorSpace;
import javax.media.jai.JAI;

import com.coolimagingproject.coolimaging.libreriaimagenes.operador.publico.ConjuntoParametroOperador;
import com.coolimagingproject.coolimaging.libreriaimagenes.operador.publico.OperadorUnario;

/**
  * El operador {@link OperadorRGB2IHS} se encarga de cambiar una imagen del
  * espacio de color RGB a IHS (intensity-hue-saturation). Esta operación está
  * implementada con los operadores de JAI.
  *
  * @see OperadorUnario
  *
  * @author L.A González Jaime
  * @author R.J Palma Durán
  *
  */
public class OperadorRGB2IHS extends OperadorUnario {
   // Espacio de color IHS
   private IHSColorSpace CS_IHS;

   // Modelo de Color
   private ComponentColorModel sistemaColorIHS;
   // Imagen a la que cambiaremos el espacio de color
   private Imagen imagenFuente;
   // Parámetros de la operación a nivel de JAI
   protected ParameterBlock parametrosJAI = new ParameterBlock();

   /**
    * Constructor
    */
   public OperadorRGB2IHS(ConjuntoParametroOperador parametros){
     super(parametros);
     // Cogemos la imagen de los parámetros
     this.imagenFuente = (Imagen)parametros.getParametro(
     PARAMETRO_IMAGEN_FUENTE).getValorParametro();

     // Comprobamos que la imagen tenga tres bandas de color
     if(this.imagenFuente.getColorModel().getNumColorComponents() < 3)
       throw new IllegalArgumentException("El espacio de color tiene menos de 3 componentes");
     // Creamos el espacio de color
     this.CS_IHS = IHSColorSpace.getInstance();

     // Extraemos el tamaño de los componentes
      int [] numBits = this.imagenFuente.getColorModel().getComponentSize();

     // Creamos el sistema de color.
     this.sistemaColorIHS = new ComponentColorModel(this.CS_IHS,
     new int[]{ numBits[0], numBits[1], numBits[2]},
     this.imagenFuente.getColorModel().hasAlpha(), this.imagenFuente
       .getColorModel().isAlphaPremultiplied(),
     this.imagenFuente.getColorModel().getTransparency(),
     this.imagenFuente.getColorModel().getTransferType());
   }

  /*
   * (non-Javadoc)
   * @see operador.Operador#operar()
   */
   public Object operar(){

     // Esta línea se debe a un bug que tiene JAI. Para más información en
     // {https://jai-core.dev.java.net/issues/show_bug.cgi?id=30}
     JAI.setDefaultTileSize(new Dimension(this.imagenFuente.getTileWidth(),
       this.imagenFuente.getTileHeight()));

     this.parametrosJAI.addSource(this.imagenFuente);
     this.parametrosJAI.add(this.sistemaColorIHS);
     // Hacemos la conversión.
     Imagen ImagenResultado = new Imagen((RenderedImage)JAI.create(
       "colorconvert", this.parametrosJAI));
     return ImagenResultado;

   }
}

En la implementación de esta operación hemos hecho uso de clases que no se han explicado en secciones anteriores. Por ejemplo, la clase que extiende OperadorRGB2IHS, OperadorUnario. Esta clase se le ofrece al desarrollador para hacer uso de ella en caso que las operaciones que implemente requieran de una sola imagen fuente. Pero ésta, no es la única clase que se puede utilizar, sino que se ofrecen otras que pretenden facilitar la tarea del desarrollador. Si desea más información de las clases que se pueden utilizar, dirijase a la sección Clases Públicas.
Otra clase relevante que se ha utilizado, es la clase Imagen, objeto que retorna y del cuál hacen uso los operadores de tratamiento de imágenes, así como los operadores de caracterización.

A diferencia de los operadores de tratamiento, los operadores de caracterización retornan objetos de tipo MC. Por ser esta estructura propia de esta aplicación, en la sección Medidas de Caracterización se explica en detalle su funcionamiento y utilización.

El operador que se ha implementado no requiere el uso de constantes o parámetros adicionales a parte del que proporciona la clase OperadorUnario (PARAMETRO_IMAGEN_FUENTE). Pero en caso que un operador requiera de parámetros adicionales, estos se pueden definir tal y cómo se expone en la sección Identificadores de Parámetros. O si desease información más detallada, puede encontrarla en la sección Cómo actua una operación en la aplicación de este manual.


Operador Aplicación

Habiendo definido el operador OperadorRGB2IHS, podemos pasar a implementar el operador del que hará uso la aplicación, es decir, el que tiene que implementar la interfaz IOperadorAplicacion.

Tal y como se ha explicado anteriormente, esta operación no requiere de parámetros adicionales, es decir, no hará uso de ningún otro parámetro a parte de la imagen fuente. Por eso utilizaremos la clase PanelInfoOperadorVacio que nos proporciona la aplicación para crear el panel de operaciones.

OperadorRGB2IHSAplicacion.java
package com.coolimagingproject.coloroperations;

import com.coolimagingproject.coolimaging.libreriaimagenes.operador.publico.ConjuntoParametroOperador;
import com.coolimagingproject.coolimaging.libreriaimagenes.operador.publico.OperadorUnario;

import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;

import com.coolimagingproject.colorOperations.operador.color.OperadorRGB2IHS;
import com.coolimagingproject.coolimaging.controlador.operador.publico.ConjuntoInformacionImagenOperador;
import com.coolimagingproject.coolimaging.controlador.operador.publico.IOperadorAplicacion;
import com.coolimagingproject.coolimaging.controlador.operador.publico.InfoOperadorAplicacion;
import com.coolimagingproject.coolimaging.controlador.operador.publico.InformacionImagenOperador;
import com.coolimagingproject.coolimaging.vista.operador.panelesOperadores.publico.PanelInfoOperador;
import com.coolimagingproject.coolimaging.vista.operador.panelesOperadores.publico.PanelInfoOperadorVacio;


/**
  * Operador que realiza el cambio del espacio de color de RGB a IHS de una
  * imagen en la aplicación.
  *
  * @author L.A González Jaime
  * @author R.J Palma Durán
  */
  public class OperadorRGB2IHSAplicacion implements IOperadorAplicacion{
   protected PanelInfoOperador panelInfoOperador;
   protected OperadorRGB2IHS operador;
   protected ConjuntoParametroOperador parametros;
   protected InfoOperadorAplicacion infoOperador;

/**
  * Constructor por defecto sin argumentos.
  */
  public OperadorRGB2IHSAplicacion(){
     crearInfoOperador();
  }

/*
  * (non-Javadoc)
  * @see
  * com.coolimagingproject.controlador.operador.IOperadorAplicacion#getPanelInfoOperador
  * (org.eclipse.swt.widgets.Composite)
  */
  public PanelInfoOperador getPanelInfoOperador(Composite parent){
     this.panelInfoOperador = new PanelInfoOperadorVacio("Realiza la conversión de RGB a IHS",
       "Operación que realiza el cambio de espacio de color \n"
       + "de una imagen RGB a IHS \n\n"
       + "Esta operación realmente no comprueba si el sistema de \n"
       + "color es RGB, solo comprueba si es una imagen con tres bandas \n"
       + "de color. Esto quiere decir, que si el sistema de color es otro \n"
       + "que no sea RGB el resultado puede ser inesperado.", parent, SWT.NONE);
     return this.panelInfoOperador;
  }

  /*
   * (non-Javadoc)
   * @see com.coolimagingproject.controlador.operador.IOperadorAplicacion#operar()
   */
  public Object operar(){
     this.operador = new OperadorRGB2IHS(this.parametros);
     return this.operador.operar();
  }

  /*
   * (non-Javadoc)
   * @see
   * com.coolimagingproject.controlador.operador.IOperadorAplicacion#insertarParametros
   * (operador.ConjuntoParametroOperador)
   */
   public void insertarParametros(ConjuntoParametroOperador parametros){
     this.parametros = parametros;
   }

  /*
   * (non-Javadoc)
   * @see
   * com.coolimagingproject.controlador.operador.IOperadorAplicacion#getTipoOperacion()
   */
   public TipoIOperadorAplicacion getTipoOperacion(){
     return IOperadorAplicacion.TipoIOperadorAplicacion.OPERADOR_TRATAMIENTO_IMAGEN;
   }

  /*
   * (non-Javadoc)
   * @see
   * com.coolimagingproject.controlador.operador.IOperadorAplicacion#getInfoOperador()
   */
   public InfoOperadorAplicacion getInfoOperador(){
     return this.infoOperador;
   }

  /**
   * Método auxuliar que inicializa la variable this.infoOperador, creando el objeto
   * InfoOperadorAplicaicon que contiene la información asociada a este IOperadorAplicacion.
   */
   private void crearInfoOperador(){
     ConjuntoInformacionImagenOperador info = new ConjuntoInformacionImagenOperador();
     info
       .insertarInformacionImagen(new InformacionImagenOperador("Imagen",
       OperadorUnario.PARAMETRO_IMAGEN_FUENTE));
     this.infoOperador=new InfoOperadorAplicacion(
       "RGB 2 IHS", "Parámetros del operador RGB 2 IHS", info);
   }
}

Una vez implementada esta clase, ya se da por finalizada la implementación de este operador.

A partir de este punto, puede volver a repetir el proceso de extender el punto de extensión e implementar nuevas operaciones tantas veces como desee.

Cuando haya terminado de implementar todas las operaciones querrá poder incluirlas dentro de la aplicación. Para ello, tendrá que pasar a crear el plug-in que se podrá incrustar en la aplicación principal.

De manera adicional, podría resultarle de interés que las cadenas de caracteres que aparecen inmersas en el código fuente estuviesen parametrizadas en ficheros externos, de tal forma, que se pudiesen traducir a otros idiomas sin tener que modificar el código. Si usted quiere llevar a cabo esta tarea, conocida como internacionalización, en la bibliografía le adjuntamos varios manuales que le pueden servir de ayuda.