2012-01-12 30 views
8

Estoy tratando de cargar un archivo bmp para reutilizarlo en OpenGL. He encontrado un código a través de google sobre cómo cargar un archivo bmp. Tomé este código y puse una clase Bitmap en mi proyecto. La clase está lejos de estar terminada, pero ya la lectura de los encabezados de los archivos falla. Después de leer los bytes para INFOHEADER y FILEHEADER, no hay los valores correctos en mis estructuras. Algunas ideas?leyendo un archivo .bmp en C++

// 
// Bitmap.h 
// 

#ifndef LaserMaze_Bitmap_h 
#define LaserMaze_Bitmap_h 

typedef struct      /**** BMP file header structure ****/ 
{ 
    unsigned short bfType;   /* Magic number for file */ 
    unsigned int bfSize;   /* Size of file */ 
    unsigned short bfReserved1;  /* Reserved */ 
    unsigned short bfReserved2;  /* ... */ 
    unsigned int bfOffBits;  /* Offset to bitmap data */ 
} BITMAPFILEHEADER; 

# define BF_TYPE 0x4D42    /* "MB" */ 

typedef struct      /**** BMP file info structure ****/ 
{ 
    unsigned int biSize;   /* Size of info header */ 
    int   biWidth;   /* Width of image */ 
    int   biHeight;   /* Height of image */ 
    unsigned short biPlanes;   /* Number of color planes */ 
    unsigned short biBitCount;  /* Number of bits per pixel */ 
    unsigned int biCompression; /* Type of compression to use */ 
    unsigned int biSizeImage;  /* Size of image data */ 
    int   biXPelsPerMeter; /* X pixels per meter */ 
    int   biYPelsPerMeter; /* Y pixels per meter */ 
    unsigned int biClrUsed;  /* Number of colors used */ 
    unsigned int biClrImportant; /* Number of important colors */ 
} BITMAPINFOHEADER; 

/* 
* Constants for the biCompression field... 
*/ 

# define BI_RGB  0    /* No compression - straight BGR data */ 
# define BI_RLE8  1    /* 8-bit run-length compression */ 
# define BI_RLE4  2    /* 4-bit run-length compression */ 
# define BI_BITFIELDS 3    /* RGB bitmap with RGB masks */ 

typedef struct      /**** Colormap entry structure ****/ 
{ 
    unsigned char rgbBlue;   /* Blue value */ 
    unsigned char rgbGreen;   /* Green value */ 
    unsigned char rgbRed;   /* Red value */ 
    unsigned char rgbReserved;  /* Reserved */ 
} RGBQUAD; 

class Bitmap { 
public: 
    Bitmap(const char* filename); 
    ~Bitmap(); 
    RGBQUAD* pixels; 
    BITMAPFILEHEADER fh; 
    BITMAPINFOHEADER ih; 

    private: 

}; 

#endif 

el CPP

// Bitmap.cpp 
// 

#include <iostream> 
#include <stdio.h> 

#include "Bitmap.h" 

Bitmap::Bitmap(const char* filename) { 
    FILE* file; 
    file = fopen(filename, "rb"); 

    std::cout << sizeof(BITMAPFILEHEADER) << std::endl; 

    if(file != NULL) { // file opened 
     BITMAPFILEHEADER h; 
     size_t x = fread(&h, sizeof(BITMAPFILEHEADER), 1, file); //reading the FILEHEADER 

     std::cout << x; 
     fread(&this->ih, sizeof(BITMAPINFOHEADER), 1, file); 

     fclose(file); 
    } 
} 

Respuesta

13

La cabecera tiene que ser de 2 bytes alineados.

#pragma pack(2) // Add this 

typedef struct 
{ 
    unsigned short bfType; 
    unsigned int bfSize; 
    unsigned short bfReserved1; 
    unsigned short bfReserved2; 
    unsigned int bfOffBits; 
} BITMAPFILEHEADER; 

#pragma pack() // and this 
+0

funcionó bien, gracias :) tal vez usted puede explicar por qué es necesario? – soupdiver

+3

Sin el pragma, los campos cortos se rellenan a 4 bytes. El tamaño de BITMAPFILEHEADER (sin pragma) es 20, pero en el archivo se escribe secuencialmente como 14 bytes. Entonces suceden dos cosas: (1) la estructura que lees está en mal estado (2) lees demasiado, entonces leer BITMAPINFOHEADER comienza 6 bytes demasiado tarde – Itsik

+0

muchas gracias :) – soupdiver

0

BITMAPINFOHEADER :: es necesario leer primero el biSize el fin de saber qué tan grande es la cabecera de información, no se puede confiar en sizeof().

Control hacia fuera este wiki article sobre el formato de archivo

4

¿Qué hay de dejar su carga el sistema operativo Windows para usted con LoadImage.

HBITMAP hbm = LoadImage(NULL, path, 0, 0, LR_LOADFROMFILE|LR_CREATEDIBSECTION); 

Uso GetObject() para encontrar más información como el tamaño, etc., y GetDIBits() si quiere llegar a los bits individuales.

+0

¿No está relacionado con esta ventana? – soupdiver

+0

Sí. No especificó el sistema operativo, así que asumí Windows. Ignora si ese no es el caso. – jschroedl