2012-01-12 54 views
8

Tôi đang cố gắng tải tệp bmp để sử dụng lại trong opengl. Tôi đã tìm thấy một số mã thông qua google về cách tải một tệp bmp. Tôi lấy mã này và đưa vào một lớp Bitmap trong dự án của tôi. Lớp học cách xa hoàn thành nhưng đã đọc các tiêu đề của tệp bị lỗi. Sau khi đọc các byte cho INFOHEADER và FILEHEADER, không có giá trị đúng trong cấu trúc của tôi. Một số ý tưởng?đọc tệp .bmp bằng 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 

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

Trả lời

13

Tiêu đề cần được gắn kết 2 byte.

#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

làm việc tốt nhờ :) có thể bạn có thể giải thích lý do tại sao điều này là cần thiết? – soupdiver

+3

Nếu không có pragma, các trường ngắn sẽ được đệm thành 4 byte. Kích thước của BITMAPFILEHEADER (w/o pragma) là 20, nhưng trong tệp nó được viết tuần tự là 14 byte. Vì vậy, hai điều xảy ra: (1) cấu trúc bạn đọc là sai lầm (2) bạn đọc quá nhiều, vì vậy đọc BITMAPINFOHEADER bắt đầu 6 byte quá muộn – Itsik

+0

cảm ơn rất nhiều :) – soupdiver

0

BITMAPINFOHEADER :: Bạn cần phải đọc đầu tiên biSize để biết làm thế nào lớn tiêu đề thông tin là, bạn không thể dựa vào sizeof().

Check-out wiki article này về định dạng tập tin

4

Làm thế nào về việc cho phép tải hệ điều hành Windows của bạn điều đó cho bạn với LoadImage.

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

Sử dụng GetObject() để tìm biết thêm thông tin như kích thước, vv và GetDIBits() nếu bạn muốn nhận được ở các bit riêng lẻ.

+0

không phải là cửa sổ này liên quan? – soupdiver

+0

Đúng. Bạn đã không chỉ định hệ điều hành vì vậy tôi giả định Windows. Bỏ qua nếu đó không phải là trường hợp. – jschroedl