2012-01-12 2 views
8

OpenGL에서 다시 사용하기 위해 bmp 파일을로드하려고합니다. bmp 파일을로드하는 방법에 대한 Google을 통해 몇 가지 코드를 발견했습니다. 이 코드를 가져 와서 프로젝트의 클래스 비트 맵에 넣었습니다. 클래스가 끝나지 않았지만 이미 파일 헤더 읽기가 잘못되었습니다. INFOHEADER 및 FILEHEADER에 대한 바이트를 읽은 후 내 구조체에 올바른 값이 없습니다. 몇 가지 아이디어가 있습니까?C++에서 .bmp 파일 읽기

// 
// 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 

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); 
    } 
} 

답변

13

헤더는 2 바이트 정렬되어야한다.

#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

감사합니다. 아마 이것이 왜 필요한지 설명 할 수 있습니까? – soupdiver

+3

pragma가 없으면 짧은 필드가 4 바이트로 채워집니다. BITMAPFILEHEADER (w/o pragma 제외)의 크기는 20이지만 파일에서 14 바이트로 순차적으로 기록됩니다. 그래서 두 가지 일이 일어납니다 : (1) 읽은 구조체가 엉망입니다 (2) 너무 많이 읽으므로 BITMAPINFOHEADER를 읽는 것이 6 바이트를 너무 늦게 시작합니다 – Itsik

+0

대단히 감사합니다. – soupdiver

0

BITMAPINFOHEADER :: 당신은 정보를 헤더가 얼마나 큰 당신이 sizeof()에 의존 할 수 알기 위해 먼저 biSize 읽을 필요가있다.

체크 아웃 파일 형식

4

에 대한이 wiki article에게 어떻게 LoadImage 당신은 Windows OS 부하를시키는 약. 당신이 개별 비트에 받기를 원한다면

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

사용 GetObject()

등 크기 및 GetDIBits() 같은 추가 정보를 찾을 수 있습니다.

+0

이 창과 관련이 없습니까? – soupdiver

+0

예. 당신은 OS를 지정하지 않았으므로 Windows를 사용했습니다. 그렇지 않은 경우 무시하십시오. – jschroedl