Programming Field - プログラミング Tips

Win32APIビットマップ処理の小Tipsまとめ

WindowsのWin32APIを利用したビットマップ処理に関するちょっとしたTipsをまとめています。詳しい説明は省略していますが、「このような機能・方法もある」という水先案内的な形で掲載しています。

最小化ボタンなどの定義済みビットマップの使い方

LoadBitmapOBM_REDUCE(最小化ボタンのビットマップ)、OBM_RESTORE(元のサイズに戻すボタンのビットマップ)、OBM_CLOSE(システムメニューのアイコンのビットマップ)を指定してそれぞれのビットマップを取得することが出来ます。なお、OBM_CLOSE は2つの画像が結合されており、左側は普通の、右側はMDIシステムメニュー用となっています。また、OBM_REDUCEOBM_ZOOMOBM_RESTORE はボタンの縁付きで、OBM_REDUCEDOBM_ZOOMDOBM_RESTORED とすると、ボタンがへこんでいる版を取得できます。なお、Windows 3.1 では、OBM_REDUCEOBM_ZOOMOBM_RESTORE ビットマップからボタンの縁を取り除くのに、座標(2,2)から、元の画像サイズ-4(cx-4,cy-4)とするとアイコンのみ取得できます。

※ OBM_ のデータを使用するには、windows.h をインクルードする前に #define OEMRESOURCE と定義します。また、すべて数値で定義されているため、実際のリソース読み込みで指定する際には MAKEINTRESOURCE による変換が必要です。

HBITMAPビットマップの一部分を取得・コピー

BitBlt 関数は、HDC から HDC に指定したエリア内の画像データ(ビット)を転送します。これを利用して、複数のパーツを 1 つにまとめたビットマップから、そのパーツを抜き出すことが出来ます。ここでは、1 つのビットマップからパーツごとにビットマップを作成する関数の例を紹介します。

// hbmSrc: ビットマップのかたまり
// x, y, nWidth, nHeight: ビットマップのパーツを表す長方形の座標
// hDC, hDCMem, hDCMem2: 一時的に利用するデバイス コンテキスト
HBITMAP CreateBlockBitmap(HBITMAP hbmSrc, int x, int y,
    int nWidth, int nHeight, HDC hDC = NULL, HDC hDCMem = NULL, HDC hDCMem2 = NULL)
{
    HDC _hDC;
    HDC _hDCMem, _hDCMem2;
    HGDIOBJ hgdiBmp, hgdiBmp2;
    HBITMAP hbmRet;

    if (hDC)
        _hDC = hDC;
    else
        _hDC = NULL;                         // スクリーン
    if (hDCMem)
        _hDCMem = hDCMem;
    else
        _hDCMem = CreateCompatibleDC(_hDC);  // 一時的な利用
    if (hDCMem2)
        _hDCMem2 = hDCMem2;
    else
        _hDCMem2 = CreateCompatibleDC(_hDC); // 一時的な利用

    hbmRet = CreateCompatibleBitmap(_hDC, nWidth, nHeight);
    hgdiBmp = SelectObject(_hDCMem, hbmRet);
    hgdiBmp2 = SelectObject(_hDCMem2, hbmSrc);
    BitBlt(_hDCMem, 0, 0, nWidth, nHeight, _hDCMem2, x, y, SRCCOPY);

    // クリーンアップ
    SelectObject(_hDCMem, hgdiBmp);
    SelectObject(_hDCMem2, hgdiBmp2);
    if (!hDCMem)
        DeleteDC(_hDCMem);
    if (!hDCMem2)
        DeleteDC(_hDCMem2);

    return hbmRet;
}

白黒ビットマップのカラービットマップへの転送

白黒ビットマップをBitBltなどでカラービットマップ、またはデバイスコンテキストへ転送するとき、色は白と黒になるとは限りません。元の白い部分はSetBkColorで指定した色、黒の部分はSetTextColorで指定した色となります。これを応用すると、(逆方向も同じなので)ある背景色を使って書かれたカラービットマップに対し、SetBkColor でその色を指定し、カラービットマップを白黒ビットマップに転送することで、背景を白、それ以外を黒に出来ます。よって、そこからマスクビットマップや影を作ることが出来ます。

もちろん上述の「一部分を取得・コピー」とも組み合わせることができるので、まず1枚のビットマップに対して白黒ビットマップを作成し、実際に描画させたい場所に対してそのビットマップから一部分をマスク・コピーするといった方法を採ることができます。

最終更新日: 2006/09/01