Anda di halaman 1dari 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
Cubas García Andrea Jazmín 3TM2

Esta será la clase base de todas (excepto de CambiarFormatos), es decir,


la clase BaseImagenes será la clase padre
de AbrirImagen y TransformarImagen, y, ¿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, y posteriormente poder deshacer/rehacer imagen.
Esta clase tendrá los siguientes métodos y propiedades.

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, blanco y negro, etc.).
El listado es accesible desde el método getTodasImagenes.
 infoTodasImagenes (private): esta propiedad es un Arraylist de String
y está relacionado con la propiedad anterior, ya que irá almacenando la
información relativa a la transformación sufrida por la imagen
almacenada. Por ejemplo, cuando se almacene una imagen (dentro de
todasImagenes) porque se ha transformado en blanco y negro, también se
almacenará en esta propiedad (infoTodasImagenes) un String informando
que la imagen se ha transformado a blanco y negro. El listado es accesible
desde el método getInfoTodasImagenes.
 contadorImagen (private): esta propiedad sirve para ir llevando
constancia de en qué posición estamos actualmente en los Arraylist
anteriores. Es una variable entera (int).

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. Recibe dos parámetros, la
imagen (BufferedImage) y la información de la transformación (String).
 deshacerImagen (public): devuelve la imagen (BufferedImage)
anterior a la actual. Esta imagen se extrae de la propiedad todasImagenes.
 rehacerImagen (public): devuelve la imagen (BuffereImage)
posterior a la actual. Esta imagen se extrae de la propiedad
todasImagenes.
 informacionImagenActual (public): devuelve la información
correspondiente a la imagen actual. Esta función se debe llamar justo
después de hacer la llamada a la función
deshacerImagen/rehacerImagen, para saber a qué corresponde la
imagen.
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, en nuestro caso, desde nuestra aplicación con
interfaz de usuario. El código fuente es el siguiente:

package ClasesImagenes;
Cubas García Andrea Jazmín 3TM2

import java.awt.image.BufferedImage;
import java.util.ArrayList;

/**
*

*/
public class BaseImagenes {

private static ArrayList<BufferedImage> todasImagenes=new


ArrayList<>();
private static ArrayList<String> infoTodasImagenes=new ArrayList<>();
static private int contadorImagen=-1;

/**
* Devuelve el listado completo de todas las imágenes
*/
public static ArrayList<BufferedImage> getTodasImagenes() {
return todasImagenes;
}

/**
* Devuelve el listado completo de toda la información de las imágenes
almacenadas
* en todasImagenes
* @return
*/
public static ArrayList<String> getInfoTodasImagenes() {
return infoTodasImagenes;
}

/**
* 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, String
informacion){
todasImagenes.add(imagen);
infoTodasImagenes.add(informacion);
BaseImagenes.contadorImagen+=1;
}

/**
* Retorna la imagen anterior con respecto a la actual
* En caso de no haber imagen posterior, retorna null
*/
Cubas García Andrea Jazmín 3TM2

public BufferedImage deshacerImagen(){


//Comprueba si hay imágenes anteriores a la actual
if((BaseImagenes.contadorImagen)>0){
BaseImagenes.contadorImagen-=1;
return
BaseImagenes.todasImagenes.get(BaseImagenes.contadorImagen);
}else{
return null;
}

/**
* Retorna la imagen posterior a la actual.
* En caso de no haber imagen posterior, retorna null
* @return
*/
public BufferedImage rehacerImagen(){
//Comprueba si hay imágenes posteriores a la actual
if((BaseImagenes.contadorImagen)<BaseImagenes.todasImagenes.siz
e()-1){
BaseImagenes.contadorImagen+=1;
return
BaseImagenes.todasImagenes.get(BaseImagenes.contadorImagen);
}else{
return null;
}
}

/**
* Devuelve la información de la imagen actual
*/
public String informacionImagenActual(){
return
BaseImagenes.infoTodasImagenes.get(BaseImagenes.contadorImagen);
}
}

AbrirImagen

Esta clase se extiende (es hija) de la clase anterior (BaseImagenes), y aquí


lo que conseguimos es abrir una imagen local o a través de una URL.
Además de esto, cada vez que se haya abierto una imagen, se llamará al
método actualizarImagen, de la clase anterior (BaseImagenes), para que
quede almacenada y luego sea accesible. Los métodos de la clase son los
siguientes.

Métodos
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.
 abrirJFileChooser (private): muestra el cuadro de diálogo para
cargar una imagen local, y devuelve true si se ha seleccionado algún
archivo y false en caso de que se cancele.
 abrirImagenLocal (public): muestra un cuadro de diálogo para abrir
una imagen. En caso de que la imagen seleccionada sea correcta,
devuelve un BufferedImage de la misma. Devuelve null si no se ha podido
cargar.
 abrirImagenURL (public): devuelve un BufferedImage a partir de una
URL que contenga una imagen. En caso de que no se pueda cargar,
devuelve null.
Esta clase, como hemos dicho, de lo que se encarga es de abrir una
imagen ya sea a partir de una URL o desde archivo. El código fuente es el
siguiente:

package ClasesImagenes;

import java.awt.image.BufferedImage;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;

/**
*
*
*/
public class AbrirImagen extends BaseImagenes {
private JFileChooser selectorImage;
/**
* Muestra un mensaje de error avisando que no se ha podido cargar la imagen
*/
private void errorImagen(){
JOptionPane.showMessageDialog(null,"No se pudo cargar la imagen","Error",JOptionPane.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.selectorImage=new JFileChooser();
this.selectorImage.setDialogTitle("Choose an image");
int flag=this.selectorImage.showOpenDialog(null);
if (flag==JFileChooser.APPROVE_OPTION){
return true;
}else{
return false;
}
}
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;
if(this.abrirJFileChooser()==true){
try {
imagenRetorno = ImageIO.read(this.selectorImage.getSelectedFile());
if (imagenRetorno!=null){
super.actualizarImagen(imagenRetorno, "Imagen abierta desde archivo");
}else{
errorImagen();
}
} catch (Exception e) {
errorImagen();
}
}
return imagenRetorno;
}

/**
* 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;
try {
URL url = new URL(URLimagen);
imagenRetorno = ImageIO.read(url);
super.actualizarImagen(imagenRetorno, "Imagen abierta desde URL: " + URLimagen);
} catch (Exception e) {
errorImagen();
}
return imagenRetorno;
}

CambiarFormatos

Esta clase ya se la hemos mostrado en otra entrada (aquí), y lo que hace


es poder transformar objetos de tipo BufferedImage, Image, ImageIcon e
Icon entre ellos. Sin más comentarios, os dejo el código.

package ClasesImagenes;

import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Image;
Cubas García Andrea Jazmín 3TM2

import java.awt.image.BufferedImage;
import javax.swing.Icon;
import javax.swing.ImageIcon;

/**
*
*
*/
public class CambiarFormatos{

public Image bufferedImageToImage(BufferedImage bufferImage){


Image imgReturn = (Image)bufferImage;
return imgReturn;
}

public ImageIcon bufferedImageToImageIcon(BufferedImage bufferImage){


ImageIcon imgIconReturn = new ImageIcon(bufferImage);
return imgIconReturn;
}

public Icon bufferedImageToIcon(BufferedImage bufferImage){


ImageIcon imgIcon=new ImageIcon(bufferImage);
Icon iconReturn = (Icon)(imgIcon);
return iconReturn;
}

public BufferedImage iconToBufferedImage(Icon icon){


BufferedImage bufferImage=(BufferedImage)this.iconToImage(icon);
return bufferImage;
}

/**
* Convierte un Icon en Image https://groups.google.com/forum/#!topic/comp.lang.java.progr
*/
public Image iconToImage(Icon icon) {
if (icon instanceof ImageIcon) {
return ((ImageIcon)icon).getImage();
} else {
int w = icon.getIconWidth();
int h = icon.getIconHeight();
GraphicsEnvironment ge =
GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice gd = ge.getDefaultScreenDevice();
GraphicsConfiguration gc = gd.getDefaultConfiguration();
BufferedImage image = gc.createCompatibleImage(w, h);
Graphics2D g = image.createGraphics();
icon.paintIcon(null, g, 0, 0);
g.dispose();
return image;
}
}
Cubas García Andrea Jazmín 3TM2

public ImageIcon iconToImageIcon(Icon icon){


ImageIcon imageIconRetur=new ImageIcon(this.iconToImage(icon));
return imageIconRetur;
}

public BufferedImage imageToBufferedImage(Image image){


BufferedImage bufferReturn=(BufferedImage)image;
return bufferReturn;
}

public ImageIcon imageToImageIcon(Image image){


ImageIcon imageIconReturn=new ImageIcon(image);
return imageIconReturn;
}

public Icon imageToIcon(Image image){


ImageIcon imgIcon=new ImageIcon(image);
Icon iconReturn=(Icon)imgIcon;
return iconReturn;
}

public BufferedImage imageIconToBufferedImage(ImageIcon imageIcon){


BufferedImage bufferReturn=(BufferedImage)((Image)imageIcon.getImage());
return bufferReturn;
}

public Image imageIconToImage(ImageIcon imageIcon){


Image imgReturn=(Image)imageIcon.getImage();
return imgReturn;
}

public Icon imageIconToIcon(ImageIcon imageIcon){


Icon iconReturn=(Icon)imageIcon;
return iconReturn;
}
}

TransformarImagen

En esta clase (extendida de BaseImagenes) se harán las transformaciones a


las imágenes. En esta entrada, vamos a incluir, escala de grises, blanco y
negro, invertir imagen y filtros (rojo, verde, azul). Y como hemos puesto de
manifiesto anteriormente, además de hacer la transformación, se va a
almacenar la imagen con la información de la transformación, a través del
método actualizarImagen, de la clase base. En las posteriores entradas
iremos añadiendo más transformaciones. A continuación explicaremos un
poco las transformaciones:

Métodos
Cubas García Andrea Jazmín 3TM2

 colorRGBaSRGB (private): devuelve, a partir de una variable Color, el


entero correspondiente al sistemaSRGB.
 clonarBufferedImage (private): crea una copia exacta del
BufferedImage recibido.
 calcularMediaColor (private): recibe una variable de tipo Color, y
calcula la media de las tres componentes (RGB), devolviendo un entero
con dicho valor.
 chequearUmbral (private): recibe una variable de tipo Color y una
variable de tipo int (umbral). Comprueba si el color recibido es mayor o
igual que el umbral, y en caso afirmativo devuelve una variable Color
blanco (255,255,255), en caso contrario negra (0,0,0).
 blancoNegro (public): transforma la imagen recibida, en función del
umbral seleccionado (entre 0 y 255), a blanco y negro.
 escalaGrises (public): transforma la imagen recibida a escala de
grises, calculando, para cada píxel, la media de sus tres componentes RGB.
 invertirImagen (public): invierte los colores de la imagen, calculando,
para cada píxel, 255 menos el canal seleccionado (RGB).

Como vemos, lo único que hay que hacer es enviar un BufferedImage a la


función que queramos, y ésta nos devolverá otro BufferedImage con la
imagen transformada.
El siguiente paso será crear la interfaz de usuario en la que utilizaremos las
clases creadas.

Añadir Formulario

Una vez hecho, vamos a añadir los controles y el resultado sería algo así.
Cubas García Andrea Jazmín 3TM2

Resultado formulario

El código fuente de este formulario es:

?
package javaimagenes;

import ClasesImagenes.AbrirImagen;
import ClasesImagenes.BaseImagenes;
import ClasesImagenes.CambiarFormatos;
import ClasesImagenes.TransformarImagen;
import java.awt.image.BufferedImage;

/**
*
*
*/
public class FormPrincipal extends javax.swing.JFrame {

//Creamos los objetos que manejeramos en los eventos de los diferentes controles
//Los objetos están instanciados
BaseImagenes ObjBase=new BaseImagenes();
AbrirImagen ObjAbrir=new AbrirImagen();
CambiarFormatos ObjCambiarFormat=new CambiarFormatos();
TransformarImagen ObjTransformaImg=new TransformarImagen();

public FormPrincipal() {
initComponents();
}

private void ButtonAbrirActionPerformed(java.awt.event.ActionEvent evt) {


BufferedImage imagen=ObjAbrir.abrirImagenLocal();
if (imagen!=null){
jLabel_Imagen.setIcon(ObjCambiarFormat.bufferedImageToIcon(imagen));
}
}

private void ButtonAbrirURLActionPerformed(java.awt.event.ActionEvent evt) {


Cubas García Andrea Jazmín 3TM2

BufferedImage imagen=ObjAbrir.abrirImagenURL(TextField_URL.getText());
if (imagen!=null){
jLabel_Imagen.setIcon(ObjCambiarFormat.bufferedImageToIcon(imagen));
}
}

private void ButtonBlancoNegroActionPerformed(java.awt.event.ActionEvent evt) {


BufferedImage imagen=ObjCambiarFormat.iconToBufferedImage(jLabel_Imagen.getIcon());
imagen=ObjTransformaImg.blancoNegro(imagen, 128);
jLabel_Imagen.setIcon(ObjCambiarFormat.bufferedImageToIcon(imagen));
}

private void ButtonEscalaGrisesActionPerformed(java.awt.event.ActionEvent evt) {


BufferedImage imagen=ObjCambiarFormat.iconToBufferedImage(jLabel_Imagen.getIcon());
imagen=ObjTransformaImg.escalaGrises(imagen);
jLabel_Imagen.setIcon(ObjCambiarFormat.bufferedImageToIcon(imagen));
}

private void ButtonInvertirActionPerformed(java.awt.event.ActionEvent evt) {


BufferedImage imagen=ObjCambiarFormat.iconToBufferedImage(jLabel_Imagen.getIcon());
imagen=ObjTransformaImg.invertirImagen(imagen);
jLabel_Imagen.setIcon(ObjCambiarFormat.bufferedImageToIcon(imagen));
}

private void ButtonFiltroRojoActionPerformed(java.awt.event.ActionEvent evt) {


BufferedImage imagen=ObjCambiarFormat.iconToBufferedImage(jLabel_Imagen.getIcon());
imagen=ObjTransformaImg.filtroRojo(imagen);
jLabel_Imagen.setIcon(ObjCambiarFormat.bufferedImageToIcon(imagen));
}

private void ButtonFiltroVerdeActionPerformed(java.awt.event.ActionEvent evt) {


BufferedImage imagen=ObjCambiarFormat.iconToBufferedImage(jLabel_Imagen.getIcon());
imagen=ObjTransformaImg.filtroVerde(imagen);
jLabel_Imagen.setIcon(ObjCambiarFormat.bufferedImageToIcon(imagen));
}

private void ButtonFiltroAzulActionPerformed(java.awt.event.ActionEvent evt) {


BufferedImage imagen=ObjCambiarFormat.iconToBufferedImage(jLabel_Imagen.getIcon());
imagen=ObjTransformaImg.filtroAzul(imagen);
jLabel_Imagen.setIcon(ObjCambiarFormat.bufferedImageToIcon(imagen));
}

private void ButtonDeshacerActionPerformed(java.awt.event.ActionEvent evt) {


BufferedImage imagen=ObjBase.deshacerImagen();
if (imagen!=null){
jLabel_Imagen.setIcon(ObjCambiarFormat.bufferedImageToIcon(imagen));
TextField_Info.setText(ObjBase.informacionImagenActual());
}
}

private void ButtonRehacerActionPerformed(java.awt.event.ActionEvent evt) {


BufferedImage imagen=ObjBase.rehacerImagen();
if (imagen!=null){
jLabel_Imagen.setIcon(ObjCambiarFormat.bufferedImageToIcon(imagen));
Cubas García Andrea Jazmín 3TM2

TextField_Info.setText(ObjBase.informacionImagenActual());
}
}

De lo que se trata, en resumen es, de al evento clic de cada botón asignar


la transformación u operación que queramos realizar.
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.

Eliminamos clase inicial

Asignamos el inicio de la aplicación a nuestro formulario

Ejecutamos y ya tenemos nuestra aplicación funcionando, el resultado es


el siguiente.
Cubas García Andrea Jazmín 3TM2

Anda mungkin juga menyukai