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() y 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