ビットマップに透明のマスクをかけるには?(CImageListは使いたくない)

[戻る]
P.M.S.'s A [E-Mail] [HomePage] 2001/02/01(木) 17:41:13
ゲームとかで四角形じゃないビットマップを使いたいときかあるのですが、
どうすれば簡単にマスク(一部の色を非表示)させることができるのでしょうか?
よくほかのゲームとか使われているのだけれどそれが知りたい。

TADA 2001/02/12(月) 10:08:22
私が作った関数で良ければどうぞ!
これを使うとマスク画像を自分でいちいち作成しなくてもいいんです。これで作るので。
これは透明色をもったBITMAPを
透明にしたい所を黒にして表示した所の色はそのまま(m_hBmp_Imageに作成)
透明にしたい所を白に設定、表示した所を黒に設定(マスク)(m_hBmp_Mask に作成)
というものです。
GetDC等で取得したhDCと透明色をもったBITMAP(hSrcBitmapDC)と透明色を指定してください。
確認用とコメントしてあるのをコメントを外せば確認できます。

>簡単にマスク(一部の色を非表示)させること
ということなので表示は分かるものとして割愛します。長くなるし。

HBITMAP m_hBmp_Mask = NULL;
HBITMAP m_hBmp_Image = NULL;
//なぜm_ってついてるかというとクラスのメンバだったからですね。
//----------------------------------------------------------------
// 関数名  CreateImageMask
// 説明   イメージとマスクを作成する
// 引数     (IN)HDC hDC            デバイスコンテキスト    
//     (IN)HBITMAP hSrcBitmapDC        元のhBmp
//     (IN)COLORREF crTransParentPixel    透明色にする色
// 戻値     TRUE:成功    FALSE:失敗
BOOL CreateImageMask(HDC hDC,HBITMAP hSrcBitmapDC,COLORREF crTransParentPixel)
{
    BOOL bReturn = TRUE;

    // BITMAPのサイズの取得
    BITMAP bm;
    GetObject(hSrcBitmapDC,sizeof(BITMAP),&bm);
    int iWidth = bm.bmWidth;
    int iHeight = bm.bmHeight;
    
    HDC hSrcMemDC    = NULL,hOldSrcMem    = NULL;
    HDC hDestMemDC = NULL,hOldDestMem    = NULL;
    //
    // マスクの作成
    //
    while(1)
    {
        // 元(src)
        // デバイスと互換性のあるメモリデバイスコンテキストを作成する
        hSrcMemDC = CreateCompatibleDC(hDC);
        if(NULL == hSrcMemDC)
        {
            bReturn = FALSE;
            break;
        }
        hOldSrcMem = SelectObject(hSrcMemDC,hSrcBitmapDC);    

        // 先(dst)
        hDestMemDC = CreateCompatibleDC(hDC);
        if(NULL == hDestMemDC)
        {
            bReturn = FALSE;
            break;
        }
        // モノクロ(白黒)で取得したいので      ↓hDestMemDC(メモリDC)を使用する
        m_hBmp_Mask = CreateCompatibleBitmap(hDestMemDC,iWidth,iHeight);    // 作っただけ
        if(NULL == m_hBmp_Mask)
        {
            bReturn = FALSE;
            break;
        }
        hOldDestMem = SelectObject(hDestMemDC,m_hBmp_Mask);    // つなぐ
 
        // 転送先で白色にしたい色(透明色)を背景色に設定する
        COLORREF oldColor = SetBkColor(hSrcMemDC,crTransParentPixel);

        // 元のビットマップを先にコピーする → マスクの完成
         BitBlt(hDestMemDC,0,0,iWidth,iHeight,hSrcMemDC,0,0,SRCCOPY);

        SetBkColor(hSrcMemDC,oldColor);

        // 確認用
//        BitBlt(hDC,0,0,iWidth,iHeight,hDestMemDC,0,0,SRCCOPY);
        break;
    }
    //
    // イメージの作成
    //
    if(TRUE == bReturn)
    {
        while(1)
        {
            // デバイス適応ビットマップを作成する  ↓hDCなのはモノクロにしないため
            m_hBmp_Image = CreateCompatibleBitmap(hDC,iWidth,iHeight);    
            if(NULL == (m_hBmp_Image))
            {
                bReturn = FALSE;
                break;
            }
            SelectObject(hDestMemDC,m_hBmp_Image);    

            // BITMAPを元のメモリDCに描画する

            StretchBlt(hDestMemDC,0,0,iWidth,iHeight,hSrcMemDC,0,0,iWidth,iHeight,SRCCOPY);

            // 確認用
//            BitBlt(hDC,0,0,iWidth,iHeight,hDestMemDC,0,0,SRCCOPY);
            
            SelectObject(hSrcMemDC,m_hBmp_Mask);
            SelectObject(hDestMemDC,m_hBmp_Image);

            // 転送先で黒色にしたい色(透明色)を背景色に設定する
            COLORREF oldColor = SetBkColor(hDestMemDC,RGB(0,0,0));
            // テキスト色を白にする
            COLORREF oldText = SetTextColor(hDestMemDC,RGB(255,255,255));
            // 元(src)のビットマップ(ボール)とhBitmapでANDを取る
            BitBlt(hDestMemDC,0,0,iWidth,iHeight,hSrcMemDC,0,0,SRCAND);

            // 確認用
//            BitBlt(hDC,0,0,iWidth,iHeight,hDestMemDC,0,0,SRCCOPY);

            SetTextColor(hDestMemDC,oldText);
            SetBkColor(hDestMemDC,oldColor);
            break;
        }
    }


    // 古いビットマップを復元し、DCを削除する
    // 先(dst)
    if(NULL != hDestMemDC && NULL != hOldDestMem)
    {
        SelectObject(hDestMemDC,hOldDestMem);
    }
    if(NULL != hDestMemDC)
    {
        DeleteDC(hDestMemDC);    // 先(dst)のメモリDC解放
    }

    // 元(Src)
    if(NULL != hSrcMemDC && NULL != hOldSrcMem)
    {
        SelectObject(hSrcMemDC,hOldSrcMem);
    }
    if(NULL != hSrcMemDC)
    {
        DeleteDC(hSrcMemDC);    // 元(src)のメモリDC解放
    }

    return bReturn;
}

TADA 2001/02/12(月) 10:14:16
>透明にしたい所を黒にして表示した所の色はそのまま(m_hBmp_Imageに作成)
>透明にしたい所を白に設定、表示した所を黒に設定(マスク)(m_hBmp_Mask に作成)

透明にしたい所を黒にして表示したい所の色はそのまま(m_hBmp_Imageに作成)
透明にしたい所を白に設定、表示したい所を黒に設定(マスク)(m_hBmp_Mask に作成)

が正しいです。いぬけでした。

後(ボール)ってのも気にしないで下さい。

古いスレッドには追加発言できません。