You are on page 1of 14

Cubas García Andrea Jazmín 3TM2

Tomando como base el programa que copia un BMP de un archivo a otro
,realice lo siguiente. El BMP debe estar basado en una paleta de 24bits.

a. Defina una paleta de 16 tonos para el color asignado porel profesor en la
clase (Verde) . Esto es, si se le asigna el ROJO, debe buscar los códigos de 16
tonos de ROJO, desde el más claro hasta el ROJO puro.

b. Una paleta de 24 bits, tiene 2^24-1 colores. Divida este espacio de colores
en 16 segmentos.

c. Asigne a cada segmento un tono de la paleta que creó

d. Modifique el programa de copia, para que realice lo siguiente

i. Lea el valor de un pixel: 3 bytes, colóquelos en su orden correcto,
conviértalos a decimal

ii. Verifique en que segmento, de los 16, se encuentra.

iii. Una vez localizado el segmento, escriba en el archivo nuevo el código del
tono al que corresponde el segmento

e. Al final del procesamiento de cada pixel de la imagen, tendrá la misma
imagen pero en alguno de los tonos asignados. Esto es, habrá construido un
filtro para imágenes

Este programa tiene como objetivo crear filtros para imágenes, en este caso se
escogió el color verde para realizar los filtros; entonces lo primero es crear un
proyecto nuevo en Netbeans (lo llamaremos JavaImagenes), le vamos a
añadir 4 clases:

Cubas García Andrea Jazmín 3TM2 Añadiendo package Añadiendo clases Clases creadas Clase BaseImagenes .

ya que irá almacenando la información relativa a la transformación sufrida por la imagen almacenada. El listado es accesible desde el método getTodasImagenes. y.  deshacerImagen (public): devuelve la imagen (BufferedImage) anterior a la actual. El código fuente es el siguiente: package ClasesImagenes. Esta imagen se extrae de la propiedad todasImagenes. ¿para qué queremos que sea así? Pues para ir almacenando todas las imágenes abiertas o transformadas que vayan pasando por las clases AbrirImagen y TransformarImagen para así tenerlas disponibles. cuando se almacene una imagen (dentro de todasImagenes) porque se ha transformado en blanco y negro. Por ejemplo. Esta imagen se extrae de la propiedad todasImagenes. la imagen (BufferedImage) y la información de la transformación (String).  infoTodasImagenes (private): esta propiedad es un Arraylist de String y está relacionado con la propiedad anterior. Esta clase de lo que trata es de ir almacenando todas las imágenes (con su correspondiente explicación) para que luego éstas sean accesibles desde el exterior de las clases. Esta función se debe llamar justo después de hacer la llamada a la función deshacerImagen/rehacerImagen.  rehacerImagen (public): devuelve la imagen (BuffereImage) posterior a la actual. para saber a qué corresponde la imagen. es decir. también se almacenará en esta propiedad (infoTodasImagenes) un String informando que la imagen se ha transformado a blanco y negro.  informacionImagenActual (public): devuelve la información correspondiente a la imagen actual. y posteriormente poder deshacer/rehacer imagen. Métodos/Funciones:  actualizarImagen (protected): este método se utilizar para almacenar la imagen transformada y la información en los Arraylist todasImagenes e infoTodasImagenes. etc. en nuestro caso. desde nuestra aplicación con interfaz de usuario. Cubas García Andrea Jazmín 3TM2 Esta será la clase base de todas (excepto de CambiarFormatos). Recibe dos parámetros. Propiedades:  todasImagenes (private): esta propiedad será un Arraylist de BufferedImage y almacenará todas las imágenes que se vayan abriendo o que sufran alguna transformación (escala de grises. la clase BaseImagenes será la clase padre de AbrirImagen y TransformarImagen. Es una variable entera (int). blanco y negro.).  contadorImagen (private): esta propiedad sirve para ir llevando constancia de en qué posición estamos actualmente en los Arraylist anteriores. El listado es accesible desde el método getInfoTodasImagenes. . Esta clase tendrá los siguientes métodos y propiedades.

retorna null */ . String informacion){ todasImagenes. import java.BufferedImage. private static ArrayList<String> infoTodasImagenes=new ArrayList<>(). } /** * Retorna la imagen anterior con respecto a la actual * En caso de no haber imagen posterior. Cubas García Andrea Jazmín 3TM2 import java. BaseImagenes.add(imagen). } /** * Almacena una imagen junto con su información para que luego sea accesible * @param imagen imagen que se quiere almacenar * @param informacion información de la imagen almacenada */ protected void actualizarImagen(BufferedImage imagen. } /** * Devuelve el listado completo de toda la información de las imágenes almacenadas * en todasImagenes * @return */ public static ArrayList<String> getInfoTodasImagenes() { return infoTodasImagenes. /** * Devuelve el listado completo de todas las imágenes */ public static ArrayList<BufferedImage> getTodasImagenes() { return todasImagenes.image. static private int contadorImagen=-1. infoTodasImagenes.util. /** * */ public class BaseImagenes { private static ArrayList<BufferedImage> todasImagenes=new ArrayList<>().add(informacion).awt.ArrayList.contadorImagen+=1.

contadorImagen-=1.contadorImagen). de la clase anterior (BaseImagenes). para que quede almacenada y luego sea accesible.contadorImagen)>0){ BaseImagenes. } } /** * Retorna la imagen posterior a la actual. } } /** * Devuelve la información de la imagen actual */ public String informacionImagenActual(){ return BaseImagenes. }else{ return null. } } AbrirImagen Esta clase se extiende (es hija) de la clase anterior (BaseImagenes).get(BaseImagenes. Además de esto. return BaseImagenes. * En caso de no haber imagen posterior.contadorImagen). retorna null * @return */ public BufferedImage rehacerImagen(){ //Comprueba si hay imágenes posteriores a la actual if((BaseImagenes.todasImagenes. y aquí lo que conseguimos es abrir una imagen local o a través de una URL. }else{ return null.siz e()-1){ BaseImagenes.todasImagenes.contadorImagen+=1.infoTodasImagenes.contadorImagen).get(BaseImagenes.contadorImagen)<BaseImagenes. return BaseImagenes.todasImagenes. Cubas García Andrea Jazmín 3TM2 public BufferedImage deshacerImagen(){ //Comprueba si hay imágenes anteriores a la actual if((BaseImagenes.get(BaseImagenes. Los métodos de la clase son los siguientes. Métodos . se llamará al método actualizarImagen. cada vez que se haya abierto una imagen.

swing. El código fuente es el siguiente: package ClasesImagenes.ERR } /** * Carga el JFIleChooser para seleccionar imagen * @return devuelve false si la acción fue cancelada por el usuario y true si * ha seleccionado algún archivo */ private boolean abrirJFileChooser(){ this. En caso de que la imagen seleccionada sea correcta. import javax. En caso de que no se pueda cargar.JOptionPane.URL. import javax. if (flag==JFileChooser.JFileChooser. devuelve un BufferedImage de la misma.selectorImage=new JFileChooser().selectorImage. import java.JOptionPane.swing."Error".BufferedImage.net.ImageIO.  abrirJFileChooser (private): muestra el cuadro de diálogo para cargar una imagen local.imageio. como hemos dicho.showMessageDialog(null. Devuelve null si no se ha podido cargar. }else{ return false.  abrirImagenLocal (public): muestra un cuadro de diálogo para abrir una imagen.setDialogTitle("Choose an image"). import javax. y devuelve true si se ha seleccionado algún archivo y false en caso de que se cancele."No se pudo cargar la imagen".awt. } } .selectorImage. /** * Muestra un mensaje de error avisando que no se ha podido cargar la imagen */ private void errorImagen(){ JOptionPane. /** * * */ public class AbrirImagen extends BaseImagenes { private JFileChooser selectorImage.showOpenDialog(null). import java. Esta clase. devuelve null.image.  abrirImagenURL (public): devuelve un BufferedImage a partir de una URL que contenga una imagen.APPROVE_OPTION){ return true. int flag=this. Cubas García Andrea Jazmín 3TM2  errorImagen (private): muestra un mensaje de error en pantalla en caso de que no se pueda abrir la imagen. this. de lo que se encarga es de abrir una imagen ya sea a partir de una URL o desde archivo.

getSelectedFile()).Image.abrirJFileChooser()==true){ try { imagenRetorno = ImageIO.read(this.Graphics2D. } } CambiarFormatos Esta clase ya se la hemos mostrado en otra entrada (aquí).read(url). } /** * Carga una imagen a partir de una URL de internet * @param URLimagen URL de la imagen que se desea abrir * @return devuelve la imagen obtenida o null si no se pudo cargar */ public BufferedImage abrirImagenURL(String URLimagen){ BufferedImage imagenRetorno=null.awt.awt.GraphicsConfiguration. . super. if(this. import java.selectorImage. "Imagen abierta desde URL: " + URLimagen). import java. if (imagenRetorno!=null){ super. Sin más comentarios. y lo que hace es poder transformar objetos de tipo BufferedImage. } catch (Exception e) { errorImagen(). }else{ errorImagen(). Image.GraphicsEnvironment. os dejo el código.awt.awt. package ClasesImagenes. try { URL url = new URL(URLimagen). import java. import java.actualizarImagen(imagenRetorno. Cubas García Andrea Jazmín 3TM2 /** * Muestra un cuadro de diálogo para abrir una imagen desde archivo * @return devuelve la imagen seleccionada o null si no se pudo cargar */ public BufferedImage abrirImagenLocal(){ BufferedImage imagenRetorno=null. "Imagen abierta desde archivo"). imagenRetorno = ImageIO.awt. } } return imagenRetorno. } return imagenRetorno. } } catch (Exception e) { errorImagen(). import java.actualizarImagen(imagenRetorno. ImageIcon e Icon entre ellos.GraphicsDevice.

Icon. } else { int w = icon. return image. g.getIconWidth().ImageIcon.paintIcon(null.java. return imgIconReturn. int h = icon. GraphicsDevice gd = ge. icon.iconToImage(icon). BufferedImage image = gc.createCompatibleImage(w. } } .google.progr */ public Image iconToImage(Icon icon) { if (icon instanceof ImageIcon) { return ((ImageIcon)icon).getLocalGraphicsEnvironment(). /** * * */ public class CambiarFormatos{ public Image bufferedImageToImage(BufferedImage bufferImage){ Image imgReturn = (Image)bufferImage.BufferedImage.getIconHeight(). GraphicsEnvironment ge = GraphicsEnvironment. } public ImageIcon bufferedImageToImageIcon(BufferedImage bufferImage){ ImageIcon imgIconReturn = new ImageIcon(bufferImage). 0). h).getDefaultScreenDevice().getImage().swing. Graphics2D g = image. return iconReturn.awt.createGraphics(). GraphicsConfiguration gc = gd. return imgReturn. import javax. 0.getDefaultConfiguration().lang. } public BufferedImage iconToBufferedImage(Icon icon){ BufferedImage bufferImage=(BufferedImage)this.dispose(). import javax. g. Icon iconReturn = (Icon)(imgIcon). } /** * Convierte un Icon en Image https://groups.com/forum/#!topic/comp.image.swing. return bufferImage. } public Icon bufferedImageToIcon(BufferedImage bufferImage){ ImageIcon imgIcon=new ImageIcon(bufferImage). Cubas García Andrea Jazmín 3TM2 import java.

} public Icon imageToIcon(Image image){ ImageIcon imgIcon=new ImageIcon(image). return bufferReturn. blanco y negro. Y como hemos puesto de manifiesto anteriormente. escala de grises.iconToImage(icon)). En esta entrada. Icon iconReturn=(Icon)imgIcon. } public BufferedImage imageIconToBufferedImage(ImageIcon imageIcon){ BufferedImage bufferReturn=(BufferedImage)((Image)imageIcon. return iconReturn. invertir imagen y filtros (rojo. return imgReturn.getImage()). Cubas García Andrea Jazmín 3TM2 public ImageIcon iconToImageIcon(Icon icon){ ImageIcon imageIconRetur=new ImageIcon(this. azul). de la clase base. return bufferReturn. vamos a incluir. se va a almacenar la imagen con la información de la transformación. return imageIconReturn. } public Icon imageIconToIcon(ImageIcon imageIcon){ Icon iconReturn=(Icon)imageIcon. } public BufferedImage imageToBufferedImage(Image image){ BufferedImage bufferReturn=(BufferedImage)image. además de hacer la transformación. a través del método actualizarImagen. return iconReturn. return imageIconRetur. verde. } public ImageIcon imageToImageIcon(Image image){ ImageIcon imageIconReturn=new ImageIcon(image). A continuación explicaremos un poco las transformaciones: Métodos . } public Image imageIconToImage(ImageIcon imageIcon){ Image imgReturn=(Image)imageIcon. } } TransformarImagen En esta clase (extendida de BaseImagenes) se harán las transformaciones a las imágenes.getImage(). En las posteriores entradas iremos añadiendo más transformaciones.

Cubas García Andrea Jazmín 3TM2  colorRGBaSRGB (private): devuelve.255. . calculando. calculando.  clonarBufferedImage (private): crea una copia exacta del BufferedImage recibido.  blancoNegro (public): transforma la imagen recibida. Añadir Formulario Una vez hecho. a partir de una variable Color. devolviendo un entero con dicho valor. en función del umbral seleccionado (entre 0 y 255).0. Como vemos. y en caso afirmativo devuelve una variable Color blanco (255.255). para cada píxel.  escalaGrises (public): transforma la imagen recibida a escala de grises. 255 menos el canal seleccionado (RGB). en caso contrario negra (0. la media de sus tres componentes RGB. lo único que hay que hacer es enviar un BufferedImage a la función que queramos.  calcularMediaColor (private): recibe una variable de tipo Color. vamos a añadir los controles y el resultado sería algo así. y ésta nos devolverá otro BufferedImage con la imagen transformada.  invertirImagen (public): invierte los colores de la imagen.0). Comprueba si el color recibido es mayor o igual que el umbral. a blanco y negro. para cada píxel.  chequearUmbral (private): recibe una variable de tipo Color y una variable de tipo int (umbral). El siguiente paso será crear la interfaz de usuario en la que utilizaremos las clases creadas. y calcula la media de las tres componentes (RGB). el entero correspondiente al sistemaSRGB.

import java.CambiarFormatos. AbrirImagen ObjAbrir=new AbrirImagen().setIcon(ObjCambiarFormat.bufferedImageToIcon(imagen)). } private void ButtonAbrirActionPerformed(java.BaseImagenes.swing.awt. if (imagen!=null){ jLabel_Imagen. /** * * */ public class FormPrincipal extends javax. import ClasesImagenes.abrirImagenLocal().JFrame { //Creamos los objetos que manejeramos en los eventos de los diferentes controles //Los objetos están instanciados BaseImagenes ObjBase=new BaseImagenes().event. import ClasesImagenes.image. TransformarImagen ObjTransformaImg=new TransformarImagen().ActionEvent evt) { .event.awt. Cubas García Andrea Jazmín 3TM2 Resultado formulario El código fuente de este formulario es: ? package javaimagenes. } } private void ButtonAbrirURLActionPerformed(java.BufferedImage. import ClasesImagenes.awt.AbrirImagen. import ClasesImagenes.TransformarImagen. CambiarFormatos ObjCambiarFormat=new CambiarFormatos(). public FormPrincipal() { initComponents().ActionEvent evt) { BufferedImage imagen=ObjAbrir.

TextField_Info.awt.iconToBufferedImage(jLabel_Imagen.invertirImagen(imagen).setText(ObjBase.iconToBufferedImage(jLabel_Imagen.getIcon()).event.iconToBufferedImage(jLabel_Imagen.getIcon()). } private void ButtonFiltroVerdeActionPerformed(java.setIcon(ObjCambiarFormat.awt.getIcon()). imagen=ObjTransformaImg.ActionEvent evt) { BufferedImage imagen=ObjBase.awt. imagen=ObjTransformaImg.abrirImagenURL(TextField_URL.filtroVerde(imagen). imagen=ObjTransformaImg.awt.setIcon(ObjCambiarFormat.setIcon(ObjCambiarFormat.bufferedImageToIcon(imagen)).bufferedImageToIcon(imagen)). imagen=ObjTransformaImg.ActionEvent evt) { BufferedImage imagen=ObjBase.iconToBufferedImage(jLabel_Imagen.ActionEvent evt) { BufferedImage imagen=ObjCambiarFormat. .bufferedImageToIcon(imagen)).event.bufferedImageToIcon(imagen)).ActionEvent evt) { BufferedImage imagen=ObjCambiarFormat.setIcon(ObjCambiarFormat.iconToBufferedImage(jLabel_Imagen.setIcon(ObjCambiarFormat. } private void ButtonEscalaGrisesActionPerformed(java.ActionEvent evt) { BufferedImage imagen=ObjCambiarFormat.event.setIcon(ObjCambiarFormat.bufferedImageToIcon(imagen)).awt. jLabel_Imagen.deshacerImagen().awt. } private void ButtonDeshacerActionPerformed(java.event.ActionEvent evt) { BufferedImage imagen=ObjCambiarFormat.bufferedImageToIcon(imagen)). jLabel_Imagen. jLabel_Imagen.bufferedImageToIcon(imagen)).event.escalaGrises(imagen). imagen=ObjTransformaImg.iconToBufferedImage(jLabel_Imagen. } private void ButtonInvertirActionPerformed(java. Cubas García Andrea Jazmín 3TM2 BufferedImage imagen=ObjAbrir. jLabel_Imagen.event.event.rehacerImagen().informacionImagenActual()).setIcon(ObjCambiarFormat.bufferedImageToIcon(imagen)). } } private void ButtonBlancoNegroActionPerformed(java.getIcon()). jLabel_Imagen.filtroAzul(imagen).blancoNegro(imagen.filtroRojo(imagen). } } private void ButtonRehacerActionPerformed(java. if (imagen!=null){ jLabel_Imagen. imagen=ObjTransformaImg. } private void ButtonFiltroRojoActionPerformed(java.awt.getText()).ActionEvent evt) { BufferedImage imagen=ObjCambiarFormat. jLabel_Imagen. if (imagen!=null){ jLabel_Imagen.bufferedImageToIcon(imagen)). if (imagen!=null){ jLabel_Imagen.awt. 128).getIcon()).getIcon()). } private void ButtonFiltroAzulActionPerformed(java.setIcon(ObjCambiarFormat.ActionEvent evt) { BufferedImage imagen=ObjCambiarFormat.event.setIcon(ObjCambiarFormat.

El siguiente paso es eliminar la clase de inicio de nuestro proyecto (o bien abrir nuestro formulario desde el main de esa clase) y ejecutar nuestro proyecto.setText(ObjBase. . Eliminamos clase inicial Asignamos el inicio de la aplicación a nuestro formulario Ejecutamos y ya tenemos nuestra aplicación funcionando. de al evento clic de cada botón asignar la transformación u operación que queramos realizar. el resultado es el siguiente.informacionImagenActual()). en resumen es. } } } De lo que se trata. Cubas García Andrea Jazmín 3TM2 TextField_Info.

Cubas García Andrea Jazmín 3TM2 .