2013-10-10 177 views
0

我正在嘗試以C++方式讀取位圖文件。該文件有兩個標題(一個文件標題和一個圖像標題)。我成功閱讀了他們兩個。但是現在我正試圖讀取數據,就像我衝紅頭文件一樣,我失敗了。當我使用C方式讀取二進制文件時,一切都很好。這裏是代碼: im_bmp.cpp讀取二進制數據問題

#include <iostream> 
#include <fstream> 
#include "im_bmp.h" 

using namespace std; 

void read_bmp(const char* f) 
{ 
    pict I; unsigned char pix[3]; px pxl; int i = 0; 

    FILE* fl = fopen(f, "rb"); 
    fread(&I, sizeof(pict), 1, fl); 
    printf("%d\n%d\n",I.im.bpp,I.fhd.f_off); // A test to show the bit per pixel and the offset(where image data begin) 

    while(i<2) 
    { 
     fread(&pix,1,3,fl); 
     printf("%d %d %d ",pix[2],pix[1],pix[0]); // A test to show the first two pixels 
     i++; 
    } 

// The code below read binary files in the C++ way 
/* 
    ifstream ifs; 
    ifs.open(f,ios::binary); 
    ifs.read((char *)&I,sizeof(pict)); 
    cout << I.im.bpp << endl;   // It works here. It's headers 
    ifs.read((char *)&pxl,sizeof(pxl)); 
    cout << pxl.r << endl;    // It fails here to read the first pixel 
*/ 
    fclose(fl); 
} 

im_bmp.h

#ifndef IM_BMP_H_INCLUDED 
#define IM_BMP_H_INCLUDED 

#include <iostream> 
#include <fstream> 
#pragma pack(1) 

using namespace std; 
/* 
typedef int int32; 
typedef short int16; 

typedef struct px 
{ 
    unsigned char r, g, b; 
} px; 

typedef struct pict 
{ 
    int w, h; 
    px dt; 
} pict; 

struct im_hd 
{ 
    int32 hd_sz; 
    int32 wdt; 
    int32 hgt; 
    int16 im_pl; 
    int16 bpp; 
    int32 cmp; 
    int32 im_sz; 
    int32 hr; 
    int32 vr; 
    int32 clr; 
    int32 mclr; 
}; 

struct fl_hd 
{ 
    char hd[2]; 
    int32 sz; 
    int32 rsv; 
    int32 f_off; 
    im_hd im; 
}; 
*/ 

struct im_hd 
{ 
    int hd_sz; 
    int wdt; 
    int hgt; 
    short im_pl; 
    short bpp; 
    int cmp; 
    int im_sz; 
    int hr; 
    int vr; 
    int clr; 
    int mclr; 
}; 

struct fl_hd 
{ 
    char hd[2]; 
    int sz; 
    int rsv; 
    int f_off; 
    //im_hd im; 
}; 

typedef struct px 
{ 
    unsigned char r, g, b; 
} px; 

typedef struct pict 
{ 
    fl_hd fhd; 
    im_hd im; 
    //int w, h; 
    //px* dt; 
} pict; 

void read_bmp(const char* f); 

#endif // IM_BMP_H_INCLUDED 

我嘗試做這在C++,但它不工作:

ifstream ifs; 
    ifs.open(f,ios::binary); 
    ifs.read((char *)&I,sizeof(pict)); 
    cout << I.im.bpp << endl;   // It works here. It's headers 
    ifs.read((char *)&pxl,sizeof(pxl)); 
    cout << pxl.r << endl;    // It fails here to read the first pixel 
+0

Hav你檢查了'ifs'的內部標誌嗎? – Geoffroy

+0

你說「它失敗了」,但你有什麼輸出?你在期待什麼? – zakinster

回答

1

你的C++代碼工作得很好。它打印你一個奇怪的字符,因爲cout將其解釋爲char

cout << pxl.r << endl; 

嘗試才能看到整數值強制轉換爲一個int

cout << static_cast<int>(pxl.r) << endl; 

雖然,你可能有強制執行使用#pragma pack進行結構比對時,在不考慮結構尺寸的情況下讀取像素可能更安全:

ifs.read((char *)&pxl.r, sizeof (unsigned char)); 
ifs.read((char *)&pxl.g, sizeof (unsigned char)); 
ifs.read((char *)&pxl.b, sizeof (unsigned char)); 
+2

一個很好的例子說明爲什麼「它在這裏失敗」並不是一個充分的問題描述。 – Adam

+0

謝謝Zakinster,那正是我的問題,並且你解決了它。 – Patrik