...ing logging 4.0

はてなブログに移行しました。D言語の話とかいろいろ。

BITMAPINFO(DIB)からHBITMAP(DDB)を得る

CreateDIBitmap()を使う、以上。

で終わる話ではあるのですが、パックされたビットマップの場合、BITMAPINFOの先頭アドレスとBITMAPINFOHEADERの内容から、後に続くカラーマスクとカラーパレットのバイト数を算出して、ピクセルデータ列の先頭アドレスを求める必要があり、これがなかなか大変だったので、結果だけ置いておきます。

HBITMAP createHBitmap(BITMAPINFO* pbi)
{
    const uint bitsPerPixel = pbi.bmiHeader.biPlanes * pbi.bmiHeader.biBitCount;
    const uint colorMaskBytes = {
        if (pbi.bmiHeader.biCompression == BI_BITFIELDS)
            return 4 * 3; // 4 bytes * 3 masks(R,G,B)
        else
            return 0;
    }();
    const uint numPallet = {
        if (bitsPerPixel <= 8) // 1, 4, 8 bits color
        {
            if (pbi.bmiHeader.biClrUsed == 0)
                return 2 ^^ bitsPerPixel;
            else
                return pbi.bmiHeader.biClrUsed;
        }
        else if (bitsPerPixel <= 32) // 16, 24, 32 bits color
            return pbi.bmiHeader.biClrUsed;
        else
            throw new Exception("Illegal color bits bitmap");
    }();
    HDC hdc = GetDC(null);
    HBITMAP hBitmap = CreateDIBitmap(
        hdc, &pbi.bmiHeader, CBM_INIT,
        cast(ubyte*)pbi + BITMAPINFOHEADER.sizeof + colorMaskBytes + RGBQUAD.sizeof * numPallet, pbi, DIB_RGB_COLORS);
    ReleaseDC(null, hdc);
    return hBitmap;
}