El archivo PGM o Portable Gray Map es una imagen en escala de grises donde cada píxel está codificado con 1 o 2 bytes. Contiene información de encabezado y valores de escala de grises de píxeles en forma de array.
Planteamiento: La idea que se sigue para leer la imagen en formato PGMB es la siguiente:
- Abra una PGMB (imagen PGM en formato binario).
- Extraiga la información de píxeles, que luego se puede utilizar para su posterior procesamiento.
- La información del encabezado se almacena en formato ASCII y se puede leer con cualquier editor de texto, pero la información de los píxeles se almacena en una formación binaria y el editor de texto lo mostrará como un texto incomprensible.
A continuación se muestra la imagen pgm de muestra.
Información del encabezado :
- número mágico para identificar el tipo de archivo:
- Archivo binario PGM (PGMB): “P5”
- Archivo ASCII PGM (PGMA): “P2”
- Ancho en formato decimal ASCII
- Altura en formato decimal ASCII
- Valor gris máximo , formato decimal ASCII, entre 0-255
- Puede contener comentarios, indicados al comenzar la línea con un ‘#’
- Todo separado con espacios en blanco (espacios en blanco, tabulaciones, CR, LF)
Información del encabezado en gfg_logo.pgm:
P5 # sample PGMB image # gfg_logo.pgm 200 200 255
Después de la información del encabezado, hay una cuadrícula de dimensiones alto * peso que contiene los valores de píxeles en escala de grises de la imagen en formato binario.
Lectura de imagen PGMB :
- Abra la imagen en modo binario de lectura, rb .
- Compruebe si hay algún comentario presente e ignórelo.
- Lee el Número Mágico .
- Lea cualquier comentario/línea en blanco/espacio en blanco.
- Leer ancho y alto separados por espacios en blanco.
- Lea el valor máximo de gris, antes y después de cualquier espacio en blanco/comentario.
- Lea la cuadrícula (ancho * alto) de valores de píxeles, separados por espacios en blanco.
A continuación se muestra el programa para el enfoque anterior:
C
// C Program to read a PGMB image // and print its parameters #include <ctype.h> #include <stdbool.h> #include <stdio.h> #include <stdlib.h> #include <string.h> // Structure for storing the // image data typedef struct PGMImage { char pgmType[3]; unsigned char** data; unsigned int width; unsigned int height; unsigned int maxValue; } PGMImage; // Function to ignore any comments // in file void ignoreComments(FILE* fp) { int ch; char line[100]; // Ignore any blank lines while ((ch = fgetc(fp)) != EOF && isspace(ch)) ; // Recursively ignore comments // in a PGM image commented lines // start with a '#' if (ch == '#') { fgets(line, sizeof(line), fp); ignoreComments(fp); } else fseek(fp, -1, SEEK_CUR); } // Function to open the input a PGM // file and process it bool openPGM(PGMImage* pgm, const char* filename) { // Open the image file in the // 'read binary' mode FILE* pgmfile = fopen(filename, "rb"); // If file does not exist, // then return if (pgmfile == NULL) { printf("File does not exist\n"); return false; } ignoreComments(pgmfile); fscanf(pgmfile, "%s", pgm->pgmType); // Check for correct PGM Binary // file type if (strcmp(pgm->pgmType, "P5")) { fprintf(stderr, "Wrong file type!\n"); exit(EXIT_FAILURE); } ignoreComments(pgmfile); // Read the image dimensions fscanf(pgmfile, "%d %d", &(pgm->width), &(pgm->height)); ignoreComments(pgmfile); // Read maximum gray value fscanf(pgmfile, "%d", &(pgm->maxValue)); ignoreComments(pgmfile); // Allocating memory to store // img info in defined struct pgm->data = malloc(pgm->height * sizeof(unsigned char*)); // Storing the pixel info in // the struct if (pgm->pgmType[1] == '5') { fgetc(pgmfile); for (int i = 0; i < pgm->height; i++) { pgm->data[i] = malloc(pgm->width * sizeof(unsigned char)); // If memory allocation // is failed if (pgm->data[i] == NULL) { fprintf(stderr, "malloc failed\n"); exit(1); } // Read the gray values and // write on allocated memory fread(pgm->data[i], sizeof(unsigned char), pgm->width, pgmfile); } } // Close the file fclose(pgmfile); return true; } // Function to print the file details void printImageDetails(PGMImage* pgm, const char* filename) { FILE* pgmfile = fopen(filename, "rb"); // Retrieving the file extension char* ext = strrchr(filename, '.'); if (!ext) printf("No extension found" "in file %s", filename); else printf("File format" " : %s\n", ext + 1); printf("PGM File type : %s\n", pgm->pgmType); // Print type of PGM file, in ascii // and binary format if (!strcmp(pgm->pgmType, "P2")) printf("PGM File Format:" "ASCII\n"); else if (!strcmp(pgm->pgmType, "P5")) printf("PGM File Format:" " Binary\n"); printf("Width of img : %d px\n", pgm->width); printf("Height of img : %d px\n", pgm->height); printf("Max Gray value : %d\n", pgm->maxValue); // close file fclose(pgmfile); } // Driver Code int main(int argc, char const* argv[]) { PGMImage* pgm = malloc(sizeof(PGMImage)); const char* ipfile; if (argc == 2) ipfile = argv[1]; else ipfile = "gfg_logo.pgm"; printf("\tip file : %s\n", ipfile); // Process the image and print // its details if (openPGM(pgm, ipfile)) printImageDetails(pgm, ipfile); return 0; }
Producción:
Explicación:
- Cree una estructura para almacenar los detalles de la imagen PGMB y asigne memoria para la misma.
- Tome la entrada del nombre del archivo ya sea como un argumento de la línea de comandos o codificándolo en el programa.
- La función openPGM() procesa los archivos de imagen de entrada y toma el puntero de memoria y el nombre del archivo.
- La función ignoreComments() se usa para omitir cualquier comentario en el archivo. Los comentarios suelen estar presentes en la parte del encabezado y, por lo tanto, los buscamos después de leer cada propiedad.
- En la función openPGM() , lea la información del encabezado del archivo, es decir. tipo de archivo, altura, peso, etc. como se indicó anteriormente.
- Luego asigne memoria según la altura de la imagen y para cada fila, asigne memoria para el ancho de la imagen.
- El método fread() lee los valores grises y los almacena en la memoria asignada para la array de caracteres 2d de la estructura pgm .
- printImageDetails() se utiliza para imprimir los valores recuperados del archivo de imagen PGMB.
Publicación traducida automáticamente
Artículo escrito por the_alphaEye y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA