0

後でビットマップの生のピクセルデータから gdk ピックスマップを作成するときに、これらを引数として渡すことができるように、bmp から幅と高さの値を取得する必要があります。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;}
    };
}

blob を標準的な方法で行 [0] にフェッチした後

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

意味不明な値を与えるだけです

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

すなわち: 幅: 65536、高さ: 5626121834492592128

ここで何が問題なのか誰にもわかりますか?私は64ビットのLinuxボックスを使用しています。

4

3 に答える 3

2

そのようにデータを解析する場合は、推奨されませんが、少なくとも:

  • プラットフォームに依存しない正しい型を使用してください。uint16_t代わりにunsigned shortuint32_t代わりにunsigned long
  • 構造をpackedにします。

どこでも機能するわけではありませんが、少なくともx86とで機能するはずx86_64です。

主にプラットフォームとコンパイラに依存するため、推奨されません。

  • __attribute__ ((packed))gcc 拡張です。他のコンパイラでは、異なる方法で処理される場合があります。
  • 一部のプラットフォームでは、構造を密にパックすることは不可能です。他のものでは、動作が少し遅くなります。
  • リトルエンディアンのマシンでのみ動作します。
于 2012-06-28T16:17:33.073 に答える
0

この構造のunsigned long値は32ビットのみである必要があります。あなたが表示している価値を考えると、heightそれ以上のものを読んでいます。

于 2012-06-28T16:17:18.120 に答える
0

gcc 64 ビットの long 型は 64 ビット長ですが、元の構造体は Windows で 32 ビット整数として定義される LONG を使用します。

#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)

また、負の高さの値に注意してください: これは、最初のスキャン行が画像の上部にある画像を識別します (高さの labs() を取得する必要があります) 正の高さの値は、最初のスキャン行が画像の上部にある画像を識別します画像の下部にあります。

于 2012-06-28T22:12:55.657 に答える