透明色とマスク画像の作成

透明部分が黒く塗りつぶされた画像からプログラムで自動的にマスク画像を作成します。
画像の準備と描画処理を分けて、描画速度のアップを図ります。

前田稔(Maeda Minoru)の超初心者のプログラム入門

プロジェクトの設定

  1. 画像を描画する度に毎回ファイル(リソース)から画像を入力するのでは、明らかに描画速度が低下します。
    そこで「描画の準備」と「実際の描画」を分けて考えます。
    1. ファイル(リソース)から画像を入力して描画の準備を整える。
      WM_CREATE: から実行します。
    2. 実際に描画処理を行う。
      WM_PAINT: から実行します。
    3. リソースを開放して描画を終了する。
      WM_DESTROY: から実行します。
  2. 描画に必要な情報を保存する構造体を定義します。
    width,height は画像の幅と高さです。
    hBmp はビットマップのハンドルです。
    hBmpDC はビットマップの HDC のハンドルです。
        typedef struct
        {   long    width,height;
            HBITMAP hBmp;
            HDC     hBmpDC;
        }   IMG;
    
        IMG     Back;       //背景画像
        IMG     Char;       //キャラクタ画像
        IMG     Mask;       //マスク画像
        
  3. IMG で定義された情報があれば描画が可能で、描画する関数は次のようになります。
    xp,yp は描画する座標で opr はラスタオペレーションです。
        //★ IMG で定義された画像を描画する
        void  Img_View(IMG *img, HWND hwnd, long xp, long yp, DWORD opr)
        {   HDC         hdc;
            hdc= GetDC(hwnd);
            BitBlt(hdc,xp,yp,img->width,img->height,img->hBmpDC,0,0,opr);
            ReleaseDC(hWnd,hdc);
        }
        
  4. ファイルから画像を入力して IMG 構造体に画像情報を設定する関数です。
    szBitmap が BMP ファイルの名前です。
        //★ BMP のロード
        HRESULT  Img_Load(IMG *img, HWND hwnd, LPSTR szBitmap)
        {
            //BMP ファイルの入力
                :
        }
        
  5. プログラムのメインテーマである BMP ファイルを入力してマスク画像を作成する関数です。
    *img が BMP の画像用で、*msk が作成されたマスク画像を設定する構造体です。
        //★ BMP 画像のロードとマスクの作成
        BOOL  Img_Mask(IMG *img, IMG *msk, HWND hwnd, LPSTR szBitmap)
        {   HDC     hdc;
    
            //BMP 画像をロードする
            Img_Load(img, hwnd, szBitmap);
    
            //マスク画像のサイズを設定
            msk->width= img->width;
            msk->height= img->height;
    
            //マスク作成
            hdc= GetDC(hwnd);
            COLORREF oldBkColor= SetBkColor(img->hBmpDC,RGB(0,0,0));//背景色設定
            msk->hBmpDC= CreateCompatibleDC(hdc);
            msk->hBmp= CreateBitmap(msk->width,msk->height,1,1,NULL);
            SelectObject(msk->hBmpDC,msk->hBmp);
            BitBlt(msk->hBmpDC,0,0,msk->width,msk->height,img->hBmpDC,0,0,SRCCOPY);
    
            SetBkColor(img->hBmpDC,oldBkColor);
            ReleaseDC(hwnd,hdc);
            return TRUE;
        }
        
  6. マスク画像を SRCCOPY で表示して、うまく作成されていることを確認して下さい。
        case WM_PAINT:
            hdc= BeginPaint (hWnd, &ps);
            Img_View(&Mask,hWnd,100,50,SRCCOPY);
            EndPaint(hWnd, &ps);
            break;
        
  7. プログラムを終了する前に Back, Char, Mask で取得したリソースを開放して下さい。
        DeleteDC(Back.hBmpDC);
        DeleteObject(Back.hBmp);
              :
        
  8. WM_PAINT: で背景画像の上からキャラクタを表示するするソースコードは次のようになります。
        case WM_PAINT:
            hdc= BeginPaint (hWnd, &ps);
            Img_View(&Back,hWnd,0,0,SRCCOPY);
            Img_View(&Mask,hWnd,140,30,SRCAND);
            Img_View(&Char,hWnd,140,30,SRCPAINT);
            EndPaint(hWnd, &ps);
            break;
        

【演習】

  1. 次の二枚の画像を用意して下さい。
  2. プログラムを完成させて下さい。

超初心者のプログラム入門(Win32API C++)