4.7 TRABAJANDO CON IMÁGENES

 

Este último post lo voy a dedicar a como insertar imágenes, no es tan complejo como los posts anteriores que creábamos figuras, añadíamos texto, etc., sin embargo, se utilizan varias clases y métodos por lo que sería recomendable que mientras se van nombrado revisarais la API de Java para tener más información y ver su uso para cuando estéis realizando la práctica tenerlo más claro.

En la práctica se van a utilizar dos imágenes: 




Las clases con sus respectivos métodos y los paquetes que vamos a utilizar son los siguientes:



 

·         La clase Image, la imagen que incluiremos tendrá que estar almacenada en algún sitio para ello crearemos una variable de tipo Image. Esta clase tiene dos métodos getWidth() getHeigth(), estos métodos lo que hacen es guardar y capturar el ancho y alto de la imagen. Esta clase pertenece al paquete Java.awt por lo que tendremos que importar en nuestro ejercicio práctico este paquete.

·         La clase ImageIO, lo de IO viene de ouput-input, entrada y salida, permite capturar o rescatar imágenes que se encuentren fuera del programa, esta clase con su correspondiente método read() para poder leer la imagen que hay en un directorio o carpeta, este método también permite leer una imagen que este en una url o en un sitio web. Esta clase pertenece a Javax.Imageio.ImageIO, por lo que tendremos que importar también este paquete.

·         Y la clase Graphics con dos métodos drawImage() y copyArea() que permite dibujar una imagen en la lámina y determinar un área, es decir, copiar zonas en otras zonas de la lámina.

Nos creamos una clase con el siguiente código:

package swing;

 

import java.awt.Color;

import java.awt.Graphics;

import javax.swing.*;

 

public class TrabajandoImagenes {

 

       public static void main(String[] args) {

           

             MarcoConImagenes mimarco=new MarcoConImagenes();

           

             mimarco.setVisible(true);

           

             mimarco.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

 

       }

 

}

 

class MarcoConImagenes extends JFrame{

     

       public MarcoConImagenes() {

            

             setTitle("Prueba con imagenes");

           

             setBounds(250, 300, 300, 200);

           

             LaminaConImagenes milamina =new LaminaConImagenes();

           

             add(milamina);

           

             milamina.setForeground(Color.BLACK);

       }

}

 

class LaminaConImagenes extends JPanel{

     

       public void paintComponent(Graphics g) {

           

             super.paintComponent(g);

           

           

       }

     

     

}

Lo primero es almacenar la imagen en la variable de tipo imagen.

private Image imagen;

Dentro del método paint nos vamos a crear un archivo de tipo File al que vamos a llamar mimagen e indicarle donde se encuentra la imagen:

File mimagen=new File(" src/swing/coche.jpg");

A continuación  le pasamos el método read() con el parámetro de tipo File:

imagen = ImageIO.read(mimagen);

Nos da un error y si pinchamos sobre él:



Esto es debido a que este método lanza una excepción por lo que tenemos que crear un código para que solucione ese problema en el caso de que no esté la imagen o la ruta no esté bien escrita. Esto lo veremos con detalle más adelante, pero hay que indicar lo siguiente:

             try {

                   

                        imagen = ImageIO.read(mimagen);

                  } catch (IOException e) {

                       

           

                       

                  }

Al catch tenemos que indicar el tipo de excepción y el objeto del mismo. Luego dentro del catch tenemos que indicar un código que muestre el motivo por el cual no se ve la imagen:

catch (IOException e) {

                       

                        System.out.println("La imagen no se encuentra");

                       

                  } 

Ahora hay que dibujar la imagen con el método drawImage le pasamos como parámetros la imagen, luego las posiciones x e y  un objeto de tipo ImageObserver.

ImageObserver es un objeto que debe ser modificado cuando la imagen se está convirtiendo. Esto quiere decir que depende de la naturaleza de la imagen que queramos dibujar puede ser que esa imagen se dibuje instantáneamente o tarde un tiempo en dibujarse porque puede ser una imagen fractal se dibuja pixel a pixel, en este caso si quieres notificar cómo va el proceso de generación de la imagen necesitas un objeto, un observador al que indicárselo que puede ser el marco o la lámina, en nuestro caso nos va a dar igual ya que no lo vamos a necesitar porque nuestra imagen va a aparecer al instante, así que en este parámetro indicaremos un null ya que no se va a informar del progreso de conversión de la imagen. En el código lo pondremos de la siguiente forma:

g.drawImage(imagen, 5, 5, null);

Probamos:



Otra forma de hacerlo para ahorrar líneas de código es instanciar directamente el objeto File de la siguiente manera:

  //File mimagen=new File("src/swing/coche.jpg");

            

             try {

                   

                   imagen=ImageIO.read(new File("src/swing/coche.jpg"));

                   

                  }

Imaginaros que no se encuentra la imagen o la ruta está mal escrita:



Nos daría un error y nos lo mostraría en consola, pero la aplicación se ejecutaría igual.

Vamos a cambiar la imagen para que nos muestre la esfera que también tenemos almacenada en el directorio donde está la imagen coche.jpg y vamos a cambiar las dimensiones de x e y a 0 para que nos lo muestre en la esquina superior izquierda:

try {

                   

                   imagen=ImageIO.read(new File("src/swing/bola.gif"));

                   

                  } catch (IOException e) {

                       

                        System.out.println("La imagen no se encuentra");

                       

                  }

             g.drawImage(imagen, 0, 0, null);

           

       }

Si ejecutamos la aplicación:



Vamos a utilizar el método copyArea para que la esfera aparezca repetida en toda la ventana. Los parámetros que nos pide es la posición x de la imagen, la posición y de la imagen, el ancho y alto de la imagen, distancia horizontal desde el origen y la distancia vertical desde el origen. Escribimos el método:

g.copyArea(0, 0, 15, 15, 150, 15);

Los dos primeros parámetros es donde se encuentra la imagen, los otros dos parámetros es el ancho y alto en pixeles de la imagen y los otros dos donde queremos que se copie la imagen. Probamos:



En el método copyArea cuando le indicamos donde tiene que copiarse la imagen podemos hacerlo mediante un for para no introducir valores fijos:

for(int i=0; i<300; i++) {

                 for(int j=0; j<200; j++) {

                      

                        g.copyArea(0, 0, 15, 15, 15*i, 15*j);

                 }

          }            

Este for lo que va hacer es recorrer todo el marco para copiar la esfera. Si ejecutamos:



Si redimensionamos el frame lo que estás haciendo es volver a llamar al método super.paintComponent(g); para que se vuelvan a pintar los componentes.

En este ejemplo nos ha salido perfecto porque conocíamos las dimensiones de la imagen 15 pixeles, pero si desconocemos esos datos se utilizan dos métodos getWidth y getHeight que lo que hacen es capturar el ancho y alto de una imagen.

Antes de la instrucción drawImage declaramos dos variables de tipo entero que nos declare la anchura y la altura que van a ser igual a la instancia de la variable imagen y el método, por parámetro le pasamos el objeto que está esperando la imagen, en este caso es la lámina.

int anchuraImagen=imagen.getWidth(this);

int alturaImagen=imagen.getHeight(this);

Se lo indicamos con la palabra clave this ya que lo estamos programando dentro de la clase lámina. Y ahora en el método copyArea:

g.copyArea(0, 0, anchuraImagen, alturaImagen, anchuraImagen*i, alturaImagen*j);

Si ejecutamos la aplicación de nuevo:



Si nos fijamos en el código la clase LaminaConImagenes no tiene constructor, creamos un constructor y le vamos a copiar el try catch:

public LaminaConImagenes() {

             try {

             

             imagen=ImageIO.read(new File("src/swing/bola.gif"));

             

            } catch (IOException e) {

                 

                  System.out.println("La imagen no se encuentra");

                 

            }

        

      }      

De esta forma cada vez que instanciemos LaminaConImagenes le estamos agregando una lámina y un estado inicial gracias al constructor que consiste en que ya tenemos una imagen cargada en memoria no pintada en la lámina.


4.6 TRABAJANDO CON FUENTES << >> 5.1 INTRODUCCIÓN A LOS EVENTOS



No hay comentarios:

Publicar un comentario