2017-09-21 42 views
2

the documentation on CreateDIBSectionCreateDIBSectionは、BITMAPINFOへのポインタを2番目のパラメータとして取ります。Windowsビットマップ:BITMAPV5HEADERおよびBITMAPINFO互換?

しかし、私には、(特にBITMAPV5HEADERで)他の構造体へのポインタを渡すことが許可される可能性があることを示すさまざまな場所に出くわした

私が持っていますこれは完璧な意味があると感じています(BITMAPV5HEADERBITMAPINFO wrt構造体レイアウトの "拡張バージョン"と見ることができます)が、このトピックに関する公式文書のece。

BITMAPINFOの代わりにを渡すことが実際に有効であり、おそらくいくつかのドキュメントを提供していることを誰でも確認できますか?

答えて

3

短い答えはで、でなければなりません。 BITMAPV5HEADER*BITMAPINFO*の代わりではなく、BITMAPINFO*が必要な場合はいつでも渡されることがあります(単にBITMAPINFOにはヘッダーの後にパレットカラーが含まれ、BITMAPV5HEADERはヘッダーにすぎません)。


BITMAPV5HEADER*代わりにBITMAPINFO*を渡す確かに微細であるがBITMAPV5HEADERBITMAPINFOの一部であり、後のパレット色データの種類を必要としていることを条件とします。それは、使用説明書と常識を介して、一種の間接が、文書化されている:部分が明確になるように

    BITMAPV5HEADER
  • は、「BITMAPINFOHEADER番目構造の拡張バージョン」とdocumentedあります。

  • BITMAPINFOは、documentedであり、ヘッダとカラーデータを組み合わせる。ヘッダーはポインタではなく値によってインクルードされるので、ヘッダーのサイズが大きくなるだけでなく、それ以外の場合はBITMAPINFO.bmiColorsにアクセスすることは不可能であり、ヘッダーの拡張バージョン無意味であろう。

  • そしてその問題は、次にanother place in the documentation(「解説」を参照)で解決され:

    次のように、BITMAPINFO構造のカラーテーブルを検索するbiSize部材に格納された情報を使用する必要があり、アプリケーション:

    pColor = ((LPSTR)pBitmapInfo + (WORD)(pBitmapInfo->bmiHeader.biSize)); 
    

私はこの部分がヨーヨーのために混乱はなかったと考えているが、最初から。


今や長い答えです。そこ

BITMAPV5HEADER*BITMAPINFO*のために渡すことができるとき例であることをに表示されます。 2のどちらも、具体的な方法で文書化され、第1の1のためならば、我々は上記の適用同じ常識を適用することができ、もう一つはマニュアルにバグに表示されます。

  • BITMAPINFO.bmiColorsがに文書化された場合NULLとなります。そのようなケースの完全なリストはdocumentation for BITMAPINFOHEADERにあります。
  • ヘッダーがBITMAPV4HEADERまたはBITMAPV5HEADERの場合、ビットマップの色は16または32ビットで、圧縮率はBI_BITFIELDSに設定されています。その場合、ヘッダーに従うように文書化されたカラーマスクは、ヘッダーのそれぞれの専用フィールドから取得され、ヘッダーに続く3つのキーは無視されます。

    これは少しoriginal codeを変更することによって、証明するのは簡単です:

    typedef struct tagV5BMPINFO { 
        BITMAPV5HEADER bmiHeader; 
        DWORD  bmiColors[3]; 
    } V5BMPINFO; 
    
    int _tmain(int argc, _TCHAR* argv[]) 
    { 
        V5BMPINFO bmpinfo = { 0 }; 
        BITMAPV5HEADER bmpheader = { 0 }; 
    
        bmpheader.bV5Size = sizeof(BITMAPV5HEADER); 
        bmpheader.bV5Width = width; 
        bmpheader.bV5Height = height; 
        bmpheader.bV5Planes = 1; 
        bmpheader.bV5BitCount = 32; 
        bmpheader.bV5Compression = BI_BITFIELDS; 
        bmpheader.bV5SizeImage = 400*200*4; 
        bmpheader.bV5RedMask = 0x00FF0000; 
        bmpheader.bV5GreenMask = 0x0000FF00; 
        bmpheader.bV5BlueMask = 0x000000FF; 
        bmpheader.bV5AlphaMask = 0xFF000000; 
        bmpheader.bV5CSType = 0x57696e20; // LCS_WINDOWS_COLOR_SPACE 
        bmpheader.bV5Intent = LCS_GM_BUSINESS; 
    
        bmpinfo.bmiHeader = bmpheader; 
        // Put them in reverse order here compared to the above 
        bmpinfo.bmiColors[0] = 0x000000FF; 
        bmpinfo.bmiColors[1] = 0x0000FF00; 
        bmpinfo.bmiColors[2] = 0x00FF0000; 
    
        void* converted = NULL; 
        HDC screen = GetDC(NULL); 
        HBITMAP result = CreateDIBSection(screen, reinterpret_cast<BITMAPINFO*>(&bmpinfo), DIB_RGB_COLORS, &converted, NULL, 0); 
        ReleaseDC(NULL, screen); 
    
    
        DIBSECTION actual_data; 
        GetObject(result, sizeof(actual_data), &actual_data); 
    
        std::cout << std::hex; 
        std::cout << actual_data.dsBitfields[0] << std::endl; 
        std::cout << actual_data.dsBitfields[1] << std::endl; 
        std::cout << actual_data.dsBitfields[2] << std::endl; 
        std::cout << std::dec; 
    
        DeleteObject(result); 
    
        return 0; 
    } 
    

    結果:

     
    ff0000 
    ff00 
    ff 
    

    時にそれが必要ドキュメントはぼんやりBITMAPINFOHEADERBITMAPV4HEADERBITMAPV5HEADER間でコピーされた表示されます最後の2つは修正されました。私は見つけることができた最も近い説明が少なくとも専用のマスクフィールドの存在を認識Bitmap Header Typesが、それでも値はこれらのフィールドにし、bmiColorsヘッダ後の両方提供されなければならない意味:

    赤、緑色、青色のビットフィールドマスクをBITMAPINFOHEADER,BITMAPV4HEADERBITMAPV5HEADER構造のすぐ後に続くビットマップマスクビットマップに置き換えます。 BITMAPV4HEADERおよびBITMAPV5HEADER構造は、以下のように、の赤、緑および青のマスクのメンバーを含んでいます。

    (強調鉱山)。

    私たちは、それが真実ではないという証拠から結論づけることができます。
    私が望んでいたよりもドキュメントの数が少なくなっています。

+0

@SGerg:@SGerg:MSDNの最初の点が見つかりました(結果が完全にわからない場合でも)。ポイント3について: 'pColor'は' bmiColors'と同じですか? https://msdn.microsoft.com/en-us/library/windows/desktop/dd183376(v=vs.85).aspxから、私は 'BI_BITFIELDS'がカラーマスクとなる' bmiColors'を示していることがわかります。私が今https://msdn.microsoft.com/en-us/library/windows/desktop/dd183381(v=vs.85).aspxを見ると、 'bV5RedMask'、' bV5GreenMask'、 'bV5BlueMask 'はそれらのカラーマスクを示し、オフセットは' bmiColors'に対応する必要があります。 – phimuemue

+0

続ける:同じオフセットのため、私は何とかBITMAPINFO *の代わりにBITMAPV5HEADER *全体を渡すことができたと思っていましたが、基本的にはBITMAPV5HEADERはすでにそれに含まれていた部分'BITMAPINFO'の' bmiColors'です。これは正しいです?あるいは、マスクに加えて「bmiColors」*を持っていますか?もう1つ:https:// expertrepliesが見つかりました。(古いMSDNの記事から取られているように見える)com/how-to-create-an-alpha-blended-cursor-or-icon-in-windows-xp /が、現在のMSDNには何も見つかりませんでした。 – phimuemue

+0

@phimuemue [Mike Ransomと同様](https://stackoverflow.com/a/4455762/11683)、BITMAPINFOは真の構造ではありません。 'bmiColors'メンバーは技術的な理由から宣言されていますが、名前で直接アクセスすることはできません。 'pColor'は' bmiColors'と同じではありませんが、 'bmiColors'だけですが、' bmiColors'は実際には物事ではありません。 'BITMAPV5HEADER'と' BITMAPV4HEADER'のどちらも 'bmiColors'データを含んでいません。' pColor'が引き続き動作するように、 'bmiColors'データに従わなければなりません。ビットマップが 'BI_BITFIELDS'を持っていない*場合*何が起こるかを考えてください。マスクが' bmiColors'と同じであれば動作しません。 – GSerg

関連する問題