Hoy vamos a empezar con Java. En esta primera entrada lo que veremos será cómo abrir una imagen y mostrarla, y cómo leer los valores de los píxeles y pasarlos a escala de grises.
Lo primero que vamos a ver es qué herramienta utilizar, en este caso vamos a descargar NetBeans, un IDE bastante completo y gratuito. Accedemos a la página:
www.oracle.com/technetwork/es/java/javase/downloads/index.html y descargamos el jdk (Java Development Kit) junto con NetBeans.
Web de descarga |
Una vez lo hemos descargado e instalado procedemos a abrir el IDE y creamos un nuevo proyecto. Para ello hacemos clic en File>New Project y seleccionamos Java Application.
Nuevo proyecto |
Le damos a siguiente (Next) y proporcionamos un nombre a nuestro proyecto, en este caso, cargarImagen y por último pulsamos el botón Finish.
Nombre del proyecto |
Una vez realizados estos pasos, se nos carga la clase inicial de nuestro proyecto, podemos ver que es el punto de partida, ya que tiene el método main. Como nuestra aplicación va a tener interfaz (GUI) vamos a eliminar esta clase para agregar un jFrame Form (el equivalente a Windows Form en Visual Studio).
Eliminar clase inicial |
Para crear este nuevo jFrame (que será el inicio de nuestra aplicación), basta con hacer clic con el botón derecho encima de nuestro paquete fuente, y se selecciona New>JFrame Form. A este formulario le vamos a llamar Principal.
Añadir nuevo JFrame |
Y con estos sencillos pasos, ya tenemos nuestro formulario que contendrá una imagen y dos botones, uno para transformar a escala de grises y otro para abrir la imagen. Para agregar una imagen no hay un contenedor específico, como podía ser PictureBox en Visual Studio, sino que vamos a asignar una imagen a un jLabel, en concreto en su propiedad Icon. El resultado de nuestro formulario es el siguiente:
Formulario principal |
A continuación, vamos a crear una clase que será la que recuperará la imagen desde archivo y contendrá la función que transforme la imagen a escala de grises. Para ello, hacemos de nuevo clic con el botón derecho encima de nuestro paquete fuente, y seleccionamos New>Java class.
Añadir clase |
A esta nueva clase le llamaremos, ProcesamientoImagen. Y vamos a incluir el siguiente código fuente:
package cargarimagen; import java.awt.Color; import java.awt.image.BufferedImage; import java.io.File; import javax.imageio.ImageIO; import javax.swing.JFileChooser; import javax.swing.filechooser.FileNameExtensionFilter; /** * * @author Luis */ public class ProcesamientoImagen { //Imagen actual que se ha cargado private BufferedImage imageActual; //Método que devuelve una imagen abierta desde archivo //Retorna un objeto BufferedImagen public BufferedImage abrirImagen(){ //Creamos la variable que será devuelta (la creamos como null) BufferedImage bmp=null; //Creamos un nuevo cuadro de diálogo para seleccionar imagen JFileChooser selector=new JFileChooser(); //Le damos un título selector.setDialogTitle("Seleccione una imagen"); //Filtramos los tipos de archivos FileNameExtensionFilter filtroImagen = new FileNameExtensionFilter("JPG & GIF & BMP", "jpg", "gif", "bmp"); selector.setFileFilter(filtroImagen); //Abrimos el cuadro de diálog int flag=selector.showOpenDialog(null); //Comprobamos que pulse en aceptar if(flag==JFileChooser.APPROVE_OPTION){ try { //Devuelve el fichero seleccionado File imagenSeleccionada=selector.getSelectedFile(); //Asignamos a la variable bmp la imagen leida bmp = ImageIO.read(imagenSeleccionada); } catch (Exception e) { } } //Asignamos la imagen cargada a la propiedad imageActual imageActual=bmp; //Retornamos el valor return bmp; } public BufferedImage escalaGrises(){ //Variables que almacenarán los píxeles int mediaPixel,colorSRGB; Color colorAux; //Recorremos la imagen píxel a píxel for( int i = 0; i < imageActual.getWidth(); i++ ){ for( int j = 0; j < imageActual.getHeight(); j++ ){ //Almacenamos el color del píxel colorAux=new Color(this.imageActual.getRGB(i, j)); //Calculamos la media de los tres canales (rojo, verde, azul) mediaPixel=(int)((colorAux.getRed()+colorAux.getGreen()+colorAux.getBlue())/3); //Cambiamos a formato sRGB colorSRGB=(mediaPixel << 16) | (mediaPixel << 8) | mediaPixel; //Asignamos el nuevo valor al BufferedImage imageActual.setRGB(i, j,colorSRGB); } } //Retornamos la imagen return imageActual; } }
Simplemente lo que hace esta clase es abrir una imagen (devolviendo una variable del tipo BufferedImage) y pasar esa imagen a escala de grises (también devolviendo un BufferedImage).
Ahora lo que tenemos que hacer es, en nuestro formulario, hacer doble clic sobre el botón de abrir imagen y pasar a escala de grises para gestionar el evento de clic. Una vez realizado esto, incluimos el siguiente código:
//Código para cargar imagen private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) { //Transformamos el BifferedImagen a ImageIcon para poder mostrarlo en el jLabel1 jLabel1.setIcon(new ImageIcon(ObjProcesamiento.abrirImagen())); } //Código para pasar a escala de grises private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) { //Transformamos el BifferedImagen a ImageIcon para poder mostrarlo en el jLabel1 jLabel1.setIcon(new ImageIcon(ObjProcesamiento.escalaGrises())); }
El resultado final de la aplicación es el siguiente:
Resultado final |
Como hemos visto, no es algo demasiado complejo. Seguramente se pueda hacer todo de una forma más elegante, pero bueno, son mis primeros pasos en Java. Poco a poco iremos viendo más cosas y seguramente las haremos de otra forma. Cualquier duda o crítica, en los comentarios ;)
Podéis descargar el código fuente aquí:
Muchisimas gracias!!!, casi lloro!!
ResponderEliminarJajajaa muy buen aporte, gracias!!!
jajajaja. De nada!!!!
EliminarHola buenas tardes!
ResponderEliminarQuisiera saber cómo conocer
el valor del rgb de una imagen insertada a
partir de un filechooser?
:(
Este comentario ha sido eliminado por el autor.
EliminarEn la propia entrada se hace lo que comentas. Fíjate, una vez que tienes la imagen como BufferedImage, puedes obtener el valor de un píxel así:
EliminarcolorAux=new Color(this.imageActual.getRGB(i, j));
donde i es la fila y j la columna. Es decir, para obtener el color del píxel superior izquierdo de una imagen sería:
colorAux=new Color(this.imageActual.getRGB(0,0));
Si quieres recorrer toda la imagen:
//Recorremos la imagen píxel a píxel
for( int i = 0; i < imageActual.getWidth(); i++ ){
for( int j = 0; j < imageActual.getHeight(); j++ ){
//Almacenamos el color del píxel
colorAux=new Color(this.imageActual.getRGB(i, j));
}
}
Un saludo!
Pero, si solicitan que al aparecer la imagen
ResponderEliminarel usuario seleccione las coordenadas y aparezcan los valores
de RGB en cajas de texto ?
Justo como te dije.
EliminarColor colorAux=new Color(this.imageActual.getRGB(i, j));
donde i es la fila y j la columna.
Un saludo
Buenas tardes.. cómo se realiza la llamada a un metodo ( de tipo BifferedImagen ) desde el evento de un botón gracias!
ResponderEliminarHola.
EliminarEcha un vistazo a esta entrada http://algoimagen.blogspot.com.es/2013/09/java-crear-aplicacion-para.html
Hola,
ResponderEliminarEstoy tratando de implementar este código con una imagen formato PGM, y da error de java.lang.NullPointerException, Qué podría hacer?
Que tal,
ResponderEliminarEstoy tratando de implementar este código con una imagen formato PGM, y da error de java.lang.NullPointerException, Qué podría hacer?
Diseña la clase que adsorba imágenes de tipo PGM...
EliminarEste comentario ha sido eliminado por el autor.
Eliminarhola, tuve un problema con el ultimo codigo, al copiar:
ResponderEliminarjLabel1.setIcon(new ImageIcon(ObjProcesamiento.abrirImagen()));
en ImageIcon y ObjProcesamiento me dice cannot find symbol
hola gracias por la ayuda, una pregunta si quiero restablecer de
ResponderEliminarnuevo los colores como le puedo hacer
espero tu respuesta gracia
Ah excelente aporte, pero me gustaría saber como le harías para pasar de escalas de grises a la foto normal
ResponderEliminarBuenas noches como puedo regresar al color original, cual es el codigo que se utilizaria
ResponderEliminarHola buenas tardes
ResponderEliminarcomo podria hacerle si quiero que cambie por ejemplo todos los pixeles blancos a verdes,y me diera un resultado tipo andy warhol.
Muy simple. Sólo tienes que hacer un condicional que verifique que el color es blanco (las tres componentes RGB sean 255) y asignar ese píxel al color verde.
Eliminar//Almacenamos el color del píxel
colorAux=new Color(this.imageActual.getRGB(i, j));
//Comprobamos si el color es blanco
if(colorAux.getRed()==255 && colorAux.getGreen()==255 && colorAux.getBlue()==255){
//Cambiamos a formato sRGB el color verde
colorSRGB=(0 << 16) | (255 << 8) | 0;
}
Échale un vistazo a esto: http://www.uv.es/gpoei/eng/Pfc_web/generalidades/pseudocolor/pseudocolor.htm
Un saludo
hola, tuve un problema con el ultimo codigo, al copiar:
ResponderEliminarjLabel1.setIcon(new ImageIcon(ObjProcesamiento.abrirImagen()));
en ImageIcon y ObjProcesamiento me dice cannot find symbol
gracias espero tu ayuda
yo tuve el miso problema me podrias ayudar ??? como solucionaste ese error??
EliminarGracias amigo... de mucha ayuda...
ResponderEliminarHola muy buen aporte mi estimado,vas por buen camino em el mundo de java ,mi duda es la sigueinte estoy leyendo sobre int_argb , necessito que hace significa esse entero y con el barra (OR logico) y las "<<" que estas especificando hacer ya que no encuentro la explicacion detallada de esse procedimento , agradeceria tu respuesta.
ResponderEliminarHola Renato,
Eliminares aritmética binaria. De lo que se trata es de pasar un color en sistema ARGB a RGB
http://es.wikipedia.org/wiki/Espacio_de_color_sRGB
http://es.wikipedia.org/wiki/RGB
http://stackoverflow.com/questions/2615522/java-bufferedimage-getting-red-green-and-blue-individually
Hola yo estoy intentando implementar tu codigo soy nueva en java y tengo problemas con estas lineas de codigo: jLabel1.setIcon(new ImageIcon(ObjProcesamiento.abrirImagen())); y jLabel1.setIcon(new ImageIcon(ObjProcesamiento.escalaGrises())); me marca un error en ObjProcesamiento como puedo solucionar este problema??? Agradeceria tu respuesta!!!!!
ResponderEliminarEl problema es que al iniciar el codigo en "Principal" no se declara Procesamiento,
Eliminarcopia este código al inicio y listo, problema resuelto ahora deberá ejecutar sin contratiempos.
------------------------------------------------
package cargarimagen;
import java.awt.Image;
import java.awt.image.BufferedImage;
import javax.swing.ImageIcon;
/**
*
* @author Luis
*/
public class Principal extends javax.swing.JFrame {
ProcesamientoImagen ObjProcesamiento=new ProcesamientoImagen();
----------------------------------
Que tal. Muchas Gracias por la explicación pero tengo una duda con respecto al código.
ResponderEliminar¿Que es lo que hace esta linea?
colorSRGB=(mediaPixel << 16) | (mediaPixel << 8) | mediaPixel;
¿Esa instruccion cambia en dado caso que en lugar del promedio use
"(max(r,g,b)+min(r,g,b))/2"?
Lo que hace es pasar un píxel de sistema RGB a SRGB, por lo tanto esa línea no la tienes que cambiar.
ResponderEliminarPrimero calculas el promedio como dices ("(max(r,g,b)+min(r,g,b))/2") y con el dato que te resulte (entiendo que la imagen que resulte será en escala de grises), calculas el valor en sistema SRGB. Algo así sería:
promedio=(max(r,g,b)+min(r,g,b))/2;
//Cambiamos a formato sRGB
colorSRGB=(mediaPixel << 16) | (mediaPixel << 8) | mediaPixel;
//Asignamos el nuevo valor al BufferedImage
imageActual.setRGB(i, j,colorSRGB);
Un saludo
Hola Luis.
ResponderEliminarno he podido entender que hace técnicamente la siguiente línea:
//Cambiamos a formato sRGB
colorSRGB=(mediaPixel << 16) | (mediaPixel << 8) | mediaPixel;
entiendo más o menos lo de desplazamiento y los OR pero no se que hace realmente en este caso.
de antemano gracias
Primero que nada gracias por el tuto, ahora mi pregunta como puedo hacerle para rayar la imagen y con otro boton exportar ?? espero tu respuesta amigo gracias y saludos
ResponderEliminarmuchas gracias por el post, fue de mucha ayuda, saludos!!
ResponderEliminarinicialmente me salía error jLabel1.setIcon(new ImageIcon(ObjProcesamiento.abrirImagen())); y jLabel1.setIcon(new ImageIcon(ObjProcesamiento.escalaGrises()));
ResponderEliminarlo solucioné creando un objeto de la clase procesamientoimagen, pero luego al correrlo abre la imagen, pero no pasa a escala de grises, sale:
Exception in thread "main" java.lang.NullPointerException at cargar.imagen.pkg2.procesamientoimagen.escalaGrises(procesamientoimagen.java:56)
cómo puedo solucionarlo???
Muchas gracias por tu post
ResponderEliminarun pregunta
¿Como puedo pasar la imagen de la escala de grises a blanco y negro?
Puedes poner un tresholding (un valor podría ser 127) y si pasa de ese valor lo pones a 0 o sino a 255, creo que así seria.
Eliminarhola, estoy haciendo un codigo para poner marca de agua a una imagen...
ResponderEliminarpodrian ayudarme?
Y si quiero leer una imagen .pgm como le hago?
ResponderEliminarhola, yo estoy trabajando con imagen pgm Y para leer lo tengo de esta manera.. checalo aver si te sirve
EliminarScanner sc = new Scanner(new File("./foto.pgm"));
//se obtiene el tamaño de la imagen
String type = sc.next();
int columns = sc.nextInt();
int rows = sc.nextInt();
int val_max = sc.nextInt();
Buenas tardes, una pregunta...es posible que me muestre en un JPanel los bytes que va leyendo de la imagen o algo parecido? y como le haria?
ResponderEliminarSaludos!
buena noche, deseo saber como guardar la imagen que contengo dentro del label en un archivo y que me guarde con el filtro, me puede ayudar
ResponderEliminarExcelente post a seguir con la lección II...
ResponderEliminarHola una pregunta, quisiera saber para que es esta linea de codigo...
ResponderEliminarcolorSRGB=(mediaPixel << 16) | (mediaPixel << 8) | mediaPixel;
Es acaso para asignar los tres canales de RGB de la imagen? y otra pregunta, porque los valores 16 y 8? son acaso parametros apara asignar? Gracias :D
Hola colega una pregunta como puedo hacer para que me muestre el nombre de la imagen y su ubicación y de la misma manera al hacer clic me muestre las coordenadas de los pixeles. De antemano gracias.
ResponderEliminarMuy buen aporte, me fue de gran ayuda. Ahora, quería preguntarle si es posible un algoritmo que me permita contar los objetos que contenga una imagen... en java. Saludos
ResponderEliminarHola estoy tratando de Leer una imagen TIFF (Geotiff) con java, pero por alguna razón no me funciona JAI.creater, los valores de los píxeles son float de 64 bits no se si ese sea el problema.
ResponderEliminarHOLA, NECESITO ALGO PARESIDO A LA TUYO PERO QUE PUEDA MANEJAR UN SCANNER, ES DECIR NECESITO HACER UN SOFTWARE CON JAVA, QUE ME DE CONEXION A UN SCANNER
ResponderEliminarhola, como harias para hacer mediciones dentro de una imagen, como el largo y ancho de una puerta o ventana dentro de foto.
ResponderEliminarhola quisiera saber como procesar la imagen pero sin la neesidad del boton
ResponderEliminarDonde te podemos seguir? buen aporte
ResponderEliminarhola una pregunta y como le podría poner una marca de agua aun pdf con java
ResponderEliminarme puedes pasar tu codigo completo
ResponderEliminar