[BMP]CreateDIBSection | Assertion Failed!

[BMP]CreateDIBSection

CreateDIBSectionの使い方


Assertion Failed!-CreateDIBSection


HBITMAP CreateDIBSection(

 HDC hdc              // デバイスコンテキストのハンドル

 CONST BITMAPINFO *pbmi  // ビットマップデータ

 UINT iUsage            // データファイルのインジケータ

 VOID **ppvBits          // ビット値

 HANDLE hSection        // ファイルマッピングオブジェクトのハンドル

 DWORD dwOffset        // ビットマップのビット値へのオフセット

}



CreateDIBSectionWIN32APIとなります。

アプリケーションから直接書き込み可能なDIBを作成可能です。



当ブログで扱うビットマップは基本24ビットフルカラー以上なので、

第2引数のBITMAPINFOBITMAPINFOHEADERをキャストします。

参考:ビットマップのフォーマット



第3引数は「DIB_PAL_COLORS」と「DIB_RGB_COLORS」があります。

基本的にDIB_RGB_COLORSを使います。(前者は使い道わかりません)



第4引数はビットマップのイメージ部の先頭を指すポインタが得られます。

pbmi に設定されているbiWidthとbiHeightの値を元に、領域を動的に確保しています。

ここで確保された領域は、DeleteObjectにより破棄されます。



第5引数は基本NULLかと思います。値の入れ方はよくわかりません。

第6引数は、第5引数がNULLの時は無視されます。




[使用例]

簡単のため、全てOnPaint内に処理を記述します。



void CSampleDlg::OnPaint()
{
  if (IsIconic())
  {
    ・・・中略
  }
  else
  {
    CPaintDC dc(this);
    CDC dcMem;
    dcMem.CreateCompatibleDC(&dc);


    // BITMAPINFOHEADER の作成

    BITMAPINFOHEADER bih = {0};

    bih.biBitCount = 24; // 24ビットカラー
    bih.biHeight = 256;  // 高さ256
    bih.biWidth = 256;  // 幅 256
    bih.biPlanes = 1;   // 常に1
    bih.biSize = sizeof(BITMAPINFOHEADER); // 構造体のサイズ


    // カラーデータを受け取るポインタ

    BYTE *pData;


    // BITMAPINFOHEADER 情報からDIBを作成し、ハンドルを取得

    HBITMAP hbmp = ::CreateDIBSection(dc.GetSafeHdc(),
                     (BITMAPINFO*)&bih,
                     DIB_RGB_COLORS,
                     (void**)&pData,
                     NULL,
                     0);


    // 以降、pDataを操作することでカラーイメージを編集できます。

    // 今回は黒→白のグラデーションを作成してみました。

    for (int y = 0; y < bih.biHeight; y++)
    {
      for (int x = 0; x < bih.biWidth * 3; x += 3)
      {
        pData[x + y * bih.biWidth *3] = y;
        pData[x + y * bih.biWidth *3 + 1] = y;
        pData[x + y * bih.biWidth *3 + 2] = y;
      }
    }


    // CreateDIBSectionで取得したハンドルをCBitmap オブジェクトに結びつける

    CBitmap bmp;
    bmp.Attach(hbmp);


    CBitmap *old = dcMem.SelectObject(&bmp);


    // 描画

    dc.BitBlt(0, 0 ,bih.biWidth, bih.biHeight, &dcMem, 0, 0, SRCCOPY);


    dcMem.SelectObject(old);

    bmp.DeleteObject();
    dcMem.DeleteDC();

}