2012-06-28 26 views
0

我需要從bmp中獲取寬度和高度值,以便在稍後從位圖中的原始像素數據創建gdk像素圖時,可以將這些值作爲參數傳遞。 我做的BMP格式和文件頭的一些研究應該是這樣的:從cpp中的mysql blob解析BMP文件

struct Fileheader 
{ 
    unsigned short Type;   // signature - 'BM' 
    unsigned long Size;   // file size in bytes 
    unsigned short Reserved1;  // 0 
    unsigned short Reserved2;  // 0 
    unsigned long OffBits;  // offset to bitmap 
    unsigned long StructSize; // size of this struct (40) 
    unsigned long Width;   // bmap width in pixels 
    unsigned long Height;  // bmap height in pixels 
    unsigned short Planes;  // num planes - always 1 
    unsigned short BitCount;  // bits per pixel 
    unsigned long Compression; // compression flag 
    unsigned long SizeImage;  // image size in bytes 
    long   XPelsPerMeter; // horz resolution 
    long   YPelsPerMeter; // vert resolution 
    unsigned long ClrUsed;  // 0 -> color table size 
    unsigned long ClrImportant; // important color count 
    Fileheader() 
    { 
     Size=Width=Height=Planes=BitCount=Compression=SizeImage=XPelsPerMeter= YPelsPerMeter=ClrUsed=ClrImportant=Type=StructSize=Reserved1=Reserved2=OffBits=0;} 
    }; 
} 

取斑標準的方式進入行之後[0]

Fileheader fh; 
memcpy(&fh, row[0], sizeof(Fileheader)); 

會給只是胡言亂語值當

cout << "width: " << fh.Width << ", height: " << fh.Height << endl; 

即:寬度:65536,高度:5626121834492592128

有人看到這裏有什麼問題嗎?順便說一句,我在一個64位的Linux機器上。

回答

2

如果你要解析的方式,這是氣餒,至少數據:

  • 使用正確,平臺independed類型。 uint16_t而不是unsigned shortuint32_t改爲unsigned long
  • 使您的結構packed

它不會工作無處不在,但應x86x86_64至少工作。

它主要是氣餒,因爲它的平臺和編譯器相關的:

  • __attribute__ ((packed))是gcc擴展。其他編譯器可能以不同的方式處理它
  • 在某些平臺上,無法緊緊包裝結構。在別人身上,他們會慢一點。
  • 它只適用於小端機器。
+0

tyty,你的建議做到了。爲什麼不鼓勵? – Paul

0

該結構中的unsigned long值應該只有32位。鑑於你顯示的價值height你讀得比這更多。

0

類型上的gcc長64位是64位長,但原始結構使用LONG,在Windows定義爲32個整數:

#pragma pack(push,1) 
typedef struct tagBITMAPINFOHEADER { 
    DWORD biSize; // use uint32_t instead 
    LONG biWidth; // use int32_t instead 
    LONG biHeight; // use int32_t instead 
    WORD biPlanes; // use uint16_t instead 
    WORD biBitCount; // use uint16_t instead 
    DWORD biCompression; // use uint32_t instead 
    DWORD biSizeImage; // use uint32_t instead 
    LONG biXPelsPerMeter; // use int32_t instead 
    LONG biYPelsPerMeter; // use int32_t instead 
    DWORD biClrUsed; // use uint32_t instead 
    DWORD biClrImportant; // use uint32_t instead 
} BITMAPINFOHEADER, *PBITMAPINFOHEADER; 
#pragma pack(pop) 

此外,要知道負高度值:這識別第一個掃描行位於圖像頂部的圖像(您必須獲得高度的實驗室()) 正高度值標識第一個掃描行位於圖像底部的圖像。