Este sitio web usa cookies de terceros para analizar el tráfico y personalizar los anuncios. Si no está de acuerdo, abandone el sitio y no siga navegando por él. ×


6.10 Ejemplo: leer información de un fichero BMP

Ahora vamos a ver un ejemplo un poco más sofisticado: vamos a abrir un fichero que sea una imagen en formato BMP y a mostrar en pantalla si está comprimido o no.

Para eso necesitamos antes saber cómo se guarda la información en un fichero BMP, pero esto es algo fácil de localizar:

FICHEROS .BMP
Un fichero BMP está compuesto por las siguientes partes: una cabecera de fichero, una cabecera del bitmap, una tabla de colores y los bytes que definirán la imagen.

En concreto, los datos que forman la cabecera de fiochero y la cabecera de bitmap son los siguientes:

TIPO DE INFORMACIÓN

POSICIÓN EN EL ARCHIVO

Tipo de fichero (letras BM)

0-1

Tamaño del archivo

2-5

Reservado

6-7

Reservado

8-9

Inicio de los datos de la imagen

10-13

Tamaño de la cabecera de bitmap

14-17

Anchura (píxeles)

18-21

Altura (píxeles)

22-25

Número de planos

26-27

Tamaño de cada punto

28-29

Compresión (0=no comprimido)

30-33

Tamaño de la imagen

34-37

Resolución horizontal

38-41

Resolución vertical

42-45

Tamaño de la tabla de color

46-49

Contador de colores importantes

50-53


Con esta información nos basta para nuestro propósito: la compresión se indica en la posición 30 del fichero, ocupa 4 bytes (lo mismo que un “int” en los sistemas operativos de 32 bits), y si es un 0 querrá decir que la imagen no está comprimida.

Entonces lo podríamos comprobar así:

/*---------------------------*/
/*  Ejemplo en C nº 59:      */
/*  C059.C                   */
/*                           */
/*  Información sobre un     */ 
/*  fichero BMP (1)          */
/*                           */
/*  Curso de C,              */
/*    Nacho Cabanes          */
/*---------------------------*/

#include 

int main(){
    
  char nombre[60];
  FILE* fichero;
  int compresion;

  puts("Comprobador de imágenes BMP\n");
  printf("Dime el nombre del fichero: ");
  gets(nombre);
  fichero = fopen(nombre, "rb");
  if (fichero==NULL)
    puts("No encontrado\n");
  else {
    fseek(fichero, 30, SEEK_SET);   
    fread(&compresion, 1, 4, fichero);
    fclose(fichero);
    if (compression == 0) 
      puts("Sin compresión");
   else
      puts ("BMP Comprimido ");
  }
  
  return 0;
}

Ya que estamos, podemos mejorarlo un poco para que además nos muestre el ancho y el alto de la imagen, y que compruebe antes si realmente se trata de un fichero BMP:

/*---------------------------*/
/*  Ejemplo en C nº 60:      */
/*  C060.C                   */
/*                           */
/*  Información sobre un     */ 
/*  fichero BMP (2)          */
/*                           */
/*  Curso de C,              */
/*    Nacho Cabanes          */
/*---------------------------*/

#include 

int main(){
  char nombre[60];
  FILE* fichero;
  int compresion, ancho, alto;
  char marca1, marca2;

  puts("Comprobador de imágenes BMP\n");
  printf("Dime el nombre del fichero: ");
  gets(nombre);
  fichero = fopen(nombre, "rb");
  if (fichero==NULL)
    puts("No encontrado\n");
  else {
    marca1 = fgetc(fichero);  /* Leo los dos primeros bytes */
    marca2 = fgetc(fichero);
    if ((marca1 =='B') && (marca2 =='M')) { /* Si son BM */
        printf("Marca del fichero: %c%c\n", 
          marca1, marca2);
        fseek(fichero, 18, SEEK_SET);    /* Posición 18: ancho */
        fread(&ancho, 1, 4, fichero);
        printf("Ancho: %d\n", ancho);    
        fread(&alto, 1, 4, fichero);     /* Siguiente dato: alto */
        printf("Alto: %d\n", alto);    
        fseek(fichero, 4, SEEK_CUR);     /* 4 bytes después: compresión */
        fread(&compresion, 1, 4, fichero);
        fclose(fichero);
        switch (compresion) {
          case 0: puts("Sin compresión"); break;
          case 1: puts("Compresión RLE 8 bits"); break;
          case 2: puts("Compresión RLE 4 bits"); break;
          }
    } else
      printf("No parece un fichero BMP\n");  /* Si la marca no es BM */
  }
  
  return 0;
}

Ejercicios propuestos: