-1

C++ で記述された GDI オブジェクトをキャッシュする API に取り組んでおり、win32 API を模倣するさまざまな Create メソッドを実装しています。そのようなメソッドの 1 つは、パックされた DIB にCreateDIBPatternBrushPt()を取り込みます。VOID*には、ビットマップのピクセルを定義するバイト配列が直後に続く構造体がVOID*含まれます。BITMAPINFOパックされた DIB について調査しました。本、Programming Windows、およびウィキペディアによると、長さは行の長さとbiHeight(のメンバーBITMAPINFOHEADER)の積に等しくなります。

RowLength = 4 * ((bmi.bcWidth * bmi.bcBitCount + 31) / 32) ;

したがって、現在、私の考えは次のようなことです。

//copy BIMAPINFO to access width and height
//lpPackedDIB is the VOID* parameter of CreateDIBPatternBrushPt()
BITMAPINFO tmpBitmapInfo;
std::memcpy(&tmpBitmapInfo, lpPackedDIB, sizeof(BITMAPINFO));

//copy entire packed DIB
int rowLength = 4 * ((tmpBitmapInfo.bmiHeader.biWidth * tmpBitmapInfo.bmiHeader.biBitCount + 31) / 32);
std::memcpy(m_pPackedDIB, lpPackedDIB, sizeof(BITMAPINFO) + rowLength * std::abs(bitmapInfo.bmiHeader.biHeight));

これはこれを行う有効な方法のように思えますか? また、このロジックを適切にテストできるように、lpPackedDIBを使用する人がどこから来るのかを知りたいです。CreateDIBPatternBrushPt()

編集:

参照: https://msdn.microsoft.com/en-us/library/windows/desktop/dd183493(v=vs.85).aspx https://en.wikipedia.org/wiki/BMP_file_format#File_structure https:/ /www-user.tu-chemnitz.de/~heha/petzold/ch15b.htm (特に「DIB ピクセル ビット」セクション)

4

1 に答える 1

1

この回答は以前に投稿されましたが、何らかの理由で削除されました。質問に直接対処するものではありませんが、私が直面していた問題についての良い洞察を与えてくれます。ユーザーへのクレジット: Barmak Shemirani .

からCreatePatternBrush取得するために単に使用できますHBRUSHHBITAMP

または使用しますCreateDIBPatternBrushPt。ただし、パックされた dib は 14 バイトしか小さいことに注意してくださいBITMAPFILEHEADER。これにより、非常に小さなブラシに役立ちます。たとえば、2x1 緑/黒ブラシ:

typedef struct
{
    BITMAPINFOHEADER header;
    unsigned char bits[2 * 1 * 4];
} DIBSTRUCT;

const DIBSTRUCT dib =
{ 
    { sizeof(BITMAPINFOHEADER), 2, 1, 1, 32, BI_RGB, 0, 0, 0, 0, 0 },
    { 0,0xff,0,0, 0,0,0,0 }
};

HBRUSH hbrush = CreateDIBPatternBrushPt(&dib, DIB_RGB_COLORS);

ビットマップファイルからブラシを作成することもできます。dib を割り当て、スペースを追加しBITMAPINFOHEADER、テーブルに色を付けます。次に、 copy BITMAPINFOHEADER、続いてカラー テーブル (存在する場合)、その後にピクセルが続きます。例:

HBRUSH getbrush(HBITMAP hbitmap)
{
    BITMAP bm;
    GetObject(hbitmap, sizeof(bm), &bm);

    int colorCount = 0;
    if (bm.bmBitsPixel == 1) colorCount = 2;
    if (bm.bmBitsPixel == 4) colorCount = 16;
    if (bm.bmBitsPixel == 8) colorCount = 256;

    RGBQUAD rgb[256];
    if (colorCount)
    {
        HDC memdc = CreateCompatibleDC(NULL);
        HGDIOBJ oldbitmap = SelectObject(memdc, hbitmap);
        GetDIBColorTable(memdc, 0, colorCount, rgb);
        SelectObject(memdc, oldbitmap);
        DeleteDC(memdc);
    }

    BITMAPINFOHEADER bminfo = { sizeof(BITMAPINFOHEADER), 
    bm.bmWidth, bm.bmHeight, 1, bm.bmBitsPixel, BI_RGB, 0, 0, 0, 0, 0 };
    DWORD size = ((bm.bmWidth * bm.bmBitsPixel + 31) / 32) * 4 * bm.bmHeight;
    char *dib = new char[sizeof(BITMAPINFOHEADER) + colorCount * 4 + size];
    memcpy(dib, &bminfo, sizeof(BITMAPINFOHEADER));
    memcpy(dib + sizeof(BITMAPINFOHEADER), rgb, colorCount * 4);
    memcpy(dib + sizeof(BITMAPINFOHEADER) + colorCount * 4, bm.bmBits, size);
    HBRUSH hbrush = CreateDIBPatternBrushPt(dib, DIB_RGB_COLORS);

    //clearnup
    DeleteObject(hbitmap);
    delete[]dib;

    return hbrush;
}
于 2016-04-25T20:43:08.663 に答える