Leyendo imagen de formato .pgm

Iniciado por Lopardo, 18 Marzo 2009, 04:14 AM

0 Miembros y 1 Visitante están viendo este tema.

Lopardo

Hola a todos.

Tengo un problema cuando leo una imagen .pgm (también me ha pasado con otros formatos). Lo que quiero hacer es conocer todos los niveles de gris de la imagen.

La estructura de las imágenes .pgm es la siguiente:

Primera Línea: Una cadena mágica que identifica el tipo de formato, puede ser:

1. P2: Los píxeles están en formato ASCII (entre 0 y 255).

2. P5: Los píxeles están en formato Binario (cada píxel viene expresada en un byte).

nota: Apartir de aquí se puede colocar comentarios usando #.

Segunda Línea: Dos números enteros separados por un espacio en blanco (Ancho y Alto)

Tercera Línea: Un número entero que indica la máxima cantidad de niveles de grises que soporta la imagen. Generalmente es 255 que indica el máximo espectro de niveles de grises.

Apartir de aquí viene la imagen de acuerdo al formato especificado en la primera línea.

Si la cadena mágica es P2, viene una serie de números enteros separados por un espacio en blanco.

Ejemplo, si los valores que aparecen son:

64 40 230...

Si la cadena mágica es P5, viene una serie de bytes.

Ejemplo, si los bytes que aparecen son:

ACD...

En este  caso aparece el carácter A, que corresponde al valor ASCII 65 que será el valor del nivel de gris del primer píxel, el carácter C, le corresponde el valor ASCII 67 que será el nivel de gris del segundo píxel, etc.


El problema es que cuando comienzo a leer los bytes que forman parte de la imagen, hay valores que superan a 255 que son los 8 bits que corresponden a cada pixel, entonces la imagen al imprimirla en pantalla se ve mal.

El código es como sigue:

   //DATOS DE LA IMAGEN

//P2: Los valores de los píxeles vienen en formato ASCII (es decir como cifras numéricas enteras entre 0 y 255).
//P5: Los valores de los píxeles vienen en formato Binario (es decir la información de cada píxel viene expresada en un byte).
String cadenaMagica;

//Indica las dimensiones de la imagen. Ancho y alto.
String dimensiones[] = new String[2];

//Indica el valor máximo del nivel de gris.
String nivelGris;

//Representación de toda la imagen.
String imagen;

public void leer()
{
try
{
BufferedReader archivo = new BufferedReader(new FileReader(new File("1.pgm")));

cadenaMagica = archivo.readLine();
System.out.println ("Cadena Magica: "+cadenaMagica);


dimensiones = archivo.readLine().split(" ");
System.out.println ("Ancho: "+dimensiones[0]+" Alto: "+dimensiones[1]);

nivelGris = archivo.readLine();
imagen = " ";

String str = archivo.readLine();

while(str!=null)
{
imagen +=str;
str = archivo.readLine();
}
}catch(Exception exc)
{
System.out.println ("Error leyendo archivo");
}
}


Para mostar la imagen hago lo siguiente, recorro el String imagen y lo voy convirtiendo al ASCII correspondiente:


         

int nivel = 0;
for(int i=0 ; i<alto ; i++)
{
  for(int j=0 ; j<ancho ; j++)
{
    nivel = ((int)imagen.charAt(i*ancho+j));

    //Esto lo hago por el error para que sea un valor comprendido entre 0-255
    //No debería pasar esto.
    if(nivel>255)
    {
nivel = 255;
    }

    g.setColor(new Color(nivel,nivel,nivel));
    g.drawOval(iniX+j,iniY+i,1,1);
}
}


Espero su ayuda.

Gracias.

Saludos
...de la sabiduría.

escabe

Cita de: Lopardo en 18 Marzo 2009, 04:14 AM


int nivel = 0;
for(int i=0 ; i<alto ; i++)
{
  for(int j=0 ; j<ancho ; j++)
{
    nivel = ((int)imagen.charAt(i*ancho+j));

    //Esto lo hago por el error para que sea un valor comprendido entre 0-255
    //No debería pasar esto.
    if(nivel>255)
    {
nivel = 255;
    }

    g.setColor(new Color(nivel,nivel,nivel));
    g.drawOval(iniX+j,iniY+i,1,1);
}
}



El problema lo tienes en la conversión de Byte a int en nivel = ((int)imagen.charAt(i*ancho+j));  define como char la variable nivel.

Saludos.