Object Class

「Alpha Cannel 対応」画像ツールの Object Class です。

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

「Alpha Cannel 対応」画像ツールの Object Class

「Alpha Cannel 対応」画像ツールの作成には、次の Onject Class を使っています。

Image Object Class

  1. IMAGE Object Class は、画像を描画する汎用の Object Class です。
    BMP 形式だけでなく、JPEG 形式や GIF 形式の画像も描画することが出来ます。
    JPEG 形式の画像を使うときは Susie で使われている DLL(ifjpeg.spi) が必要です。
    GIF 形式の画像を使うときは Susie で使われている DLL(ifgif.spi) が必要です。
    Susie は有名なソフトなので、ネットで検索すればすぐ見つかるはずです。
    DLL は実行プログラム(*.exe)と同じフォルダーまたは、c:\Windows\System32\ のフォルダーに格納して下さい。
  2. IMAGE Object Class の基本的な使い方です。
    LoadFile() では、拡張子の先頭文字(B,J,G) で画像の形式を識別します。
    既に画像がロードされているときは、古い画像を開放してから読み込んでいます。
    次の Img->Show(); は、パラメータ無しの呼び出しで、画像全体を現在のウインドウに描画します。
        IMAGE           *Img= NULL;
        char            File[]= "c:\\data\\test.jpg";
    
        Img= new IMAGE(hwnd);
        Img->LoadFile(File);
        Img->Show();
        if (Img)
        {   delete(Img);
            Img= NULL;
        }
        
  3. Show() 関数は、次の形式がサポートされています。
    透明色を使うときは、黒(0,0,0)が透明色になります。
    HDC を省略すると GetDC(hWnd); で現在の Window の HDC を取得して描画します。
    横と縦の枚数を指定して画像をタイル状に切り出す Sprite 機能もポートします。
        //BitBlt() で描画する
        HRESULT     Show(HDC hdc,long x,long y,long w,long h,long xd,long yd);
        HRESULT     Show(long x,long y,long w,long h,long xd,long yd);
        HRESULT     Show(HDC hdc)
                    {  return Show(hdc,0,0,Width,Height,0,0);  }
        HRESULT     Show(HDC hdc,long x,long y)
                    {  return Show(hdc,x,y,Width,Height,0,0);  }
        HRESULT     Show()
                    {  return Show(0,0,Width,Height,0,0);  }
        HRESULT     Show(long x,long y)
                    {  return Show(x,y,Width,Height,0,0);  }
    
        //透明色は TransparentBlt() で描画する
        HRESULT     ShowBlack(HDC hdc,long x,long y,long w,long h,long xd,long yd);
        HRESULT     ShowBlack(long x,long y,long w,long h,long xd,long yd);
        HRESULT     ShowBlack(HDC hdc)
                    {  return ShowBlack(hdc,0,0,Width,Height,0,0);  }
        HRESULT     ShowBlack(HDC hdc,long x,long y)
                    {  return ShowBlack(hdc,x,y,Width,Height,0,0);  }
        HRESULT     ShowBlack()
                    {  return ShowBlack(0,0,Width,Height,0,0);  }
        HRESULT     ShowBlack(long x,long y)
                    {  return ShowBlack(x,y,Width,Height,0,0);  }
    
        //Sprite 番号を指定するときは、透明色を設定して TransparentBlt() で描画する
        HRESULT     Show(HDC hdc,long n,long x,long y,long w,long h,long xoff,long yoff);
        HRESULT     Show(HDC hdc,long n,long x,long y)
                    {  return Show(hdc,n,x,y,SWidth,SHeight,0,0);  }
        HRESULT     Show(long n,long x,long y,long w,long h,long xoff,long yoff);
        HRESULT     Show(long n,long x,long y)
                    {  return Show(n,x,y,SWidth,SHeight,0,0);  }
    
        //拡大/縮小は TransparentBlt() で描画する
        HRESULT     ShowSize(HDC hdc, long x, long y, float size);
        HRESULT     ShowSize(long x, long y, float size);
        HRESULT     ShowSize(HDC hdc, long n, long x, long y, float size);
        HRESULT     ShowSize(long n, long x, long y, float size);
    
        //回転は PlgBlt() で描画する
        HRESULT     ShowRot(HDC hdc, long n, long x, long y, float rt);
        HRESULT     ShowRot(long n, long x, long y, float rt);
        

Alpha32 Object Class

  1. Alpha32 Object Class は Alpha Cannel を使ったイメージファイルを描画・作成するための専用のクラスです。
  2. Alpha32 Object Class の基本的な使い方です。
    Constructor でサイズを指定して Surface を作成します。
    Alpha->LoadWBmpDC() で hBmpDC をパラメータにして画像を格納します。
        ALPHA32     *Alpha= NULL;
    
        // Alpha32 の初期化
        Alpha= new ALPHA32(hwnd,Image->Width,Image->Height);
    
        // Alpha32(WBmpDC) に Image で入力したイメージ(画像)を格納
        Alpha->LoadWBmpDC(Image->hBmpDC);
        // 入力したイメージにアルファチャネルが格納されているとき
        if (Alpha->AlphFlg==TRUE)
            MessageBox(NULL,"アルファチャネルが設定されました","Alpha Image Tool",MB_OK);
    
        // WBmpDC の RGB と A をブレンドして hBmpDC に格納する
        // ブレンド画像を描画
        hdc = BeginPaint(hWnd,&ps);
        BitBlt(hdc,0,0,Image->Width,Image->Height,Alpha->hBmpDC,0,0,SRCCOPY);
        EndPaint(hWnd, &ps);
        
  3. Alpha32.h とメンバー関数
    Constructor で Surface(画像)のサイズを指定して、二枚の 32bit Surface を生成します。
    hWBmpDC は Alpha 付き元画像を格納する Surface です。
    R,G,B の通常の画像と、A(Alpha Cannel)を使います。
    hBmpDC は描画用に加工したイメージを格納する Surface です。
    //★ Alpha32 Object Class Header   2010/10/10  Ver 1.0  前田 稔 ★
    #ifndef     _Alpha32
    #define     _Alpha32
    #define     SAFE_DELDC(p)   { if (p) { DeleteDC (p);   (p)=NULL; } }
    #define     SAFE_DELOBJ(p)  { if (p) { DeleteObject(p); (p)=NULL; } }
    
    class ALPHA32
    { protected:
        HWND            hWnd;
        HBITMAP         hBmp;               //画像の HBITMAP
        HBITMAP         hWBmp;              //ブレンド用の HBITMAP
        LPBITMAPINFO    Info;               //BITMAP 構造体のヘッダー
    
      public:
        HDC             hBmpDC;             //描画用の HDC
        HDC             hWBmpDC;            //Alpha 付き元の HDC
        long            Width;              //画像の幅
        long            Height;             //画像の高さ
        LPBYTE          Data;               //描画用のピクセルデータ
        LPBYTE          WData;              //元のピクセルデータ
        COLORREF        Mask;               //RGB マスク
        bool            AlphFlg;            //Alpha Channel Flag
    
        ALPHA32(HWND hwnd, long, long);     //Constructor
        ~ALPHA32();                         //Destructor
        HRESULT         LoadBmpDC(HDC hdc);
        HRESULT         LoadWBmpDC(HDC hdc);
        HRESULT         LoadAlph(HDC hdc, long w, long h);
        HRESULT         Wipe(LPBYTE data, float rate);
        HRESULT         Wipe(float rate);
        bool            CheckAlph();
        HRESULT         WipeAlph(float rate);
        HRESULT         AlphImage();
        HRESULT         Blend(LPBYTE data, LPBYTE wdata, float rate);
        HRESULT         Blend(float rate)  {  return Blend(Data, WData, rate);  }
        HRESULT         Show(HDC hdc, long x, long y);
        HRESULT         PutBmp32(LPSTR fname);
        HRESULT         PutBmp32();
        void            Clear(HWND hwnd, HBRUSH brush);
        void            Clear(HWND hwnd)  {  Clear(hwnd, (HBRUSH)GetStockObject(WHITE_BRUSH));  }
    };
    
    #endif
    
  4. メンバー関数の概要です。
    Constructor で元画像と描画用の二枚の 32bit Surface を生成します。
    このとき、Surface のサイズをパラメータで指定します。
    ピクセルデータを操作するには CreateDIBSection() で LPBYTE を取得します。
    // Constructor(Surface のサイズが決まる)
    ALPHA32::ALPHA32(HWND hwnd, long width, long height)
    {   HDC     hDC;
    
        hWnd= hwnd;
        Width= width;
        Height= height;
        // 32bit DIB 作成
        hDC = GetDC(hWnd);
        Info = (LPBITMAPINFO)GlobalAlloc(GPTR,sizeof(BITMAPINFO));
        Info-> bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
        Info-> bmiHeader.biWidth=Width;
        Info-> bmiHeader.biHeight=Height;
        Info-> bmiHeader.biPlanes=1;
        Info-> bmiHeader.biBitCount=32;         // 32 bit
        Info-> bmiHeader.biCompression=BI_RGB;  // 非圧縮
        hBmp=  CreateDIBSection(hDC,Info,0,(void**)&Data,NULL,0); 
        hBmpDC= CreateCompatibleDC(hDC);        // hBmpDC と hBmp を関連付ける
        SelectObject(hBmpDC,hBmp);
        hWBmp= CreateDIBSection(hDC,Info,0,(void**)&WData,NULL,0); 
        hWBmpDC= CreateCompatibleDC(hDC);
        SelectObject(hWBmpDC,hWBmp);
        GlobalFree(Info);
        ReleaseDC(hWnd,hDC);
        Mask= RGB(0,0,0);
        AlphFlg= FALSE;
    }
    
  5. イメージ画像を hWBmpDC に格納する LoadWBmpDC() 関数です。
    Constructor でサイズを指定して、元画像の Surface(hWBmpDC) は生成済です。
    入力したイメージがアルファチャネル付のときは hWBmpDC の Alph(A) にもデータが格納されています。
    アルファチャネルが設定されているかを CheckAlph() でチェックします。
    // HDC hdc のイメージを hWBmpDC に格納する
    HRESULT  ALPHA32::LoadWBmpDC(HDC hdc)
    {
        if (hWBmpDC==NULL)  return FALSE;
        BitBlt(hWBmpDC,0,0,Width,Height,hdc,0,0,SRCCOPY);
        AlphFlg= CheckAlph();
        return TRUE;
    }
    
  6. マスク画像をロードする LoadAlph() 関数です。
    マスク画像の青色要素を、元画像(hWBmpDC) の Alpha Cannel に格納します。
    // hBmpDC にマスク画像をロードして、青を hWBmpDC の Alpha Cannel に格納する
    HRESULT  ALPHA32::LoadAlph(HDC hdc, long w, long h)
    {   LONG    dx,dy;
        BYTE    b;
        long    ws,hs;
    
        ws= Width;
        hs= Height;
        if (ws>w)	ws= w;
        if (hs>h)	ws= h;
        BitBlt(hBmpDC,0,0,ws,hs,hdc,0,0,SRCCOPY);
        // 青をα値に格納
        for(dy=0; dy<hs; dy++)
            for(dx=0; dx<ws; dx++)
            {   b= Data[(dy*Width+dx)*4];
                WData[(dy*Width+dx)*4+3] = b;
            }
        AlphFlg= CheckAlph();
        return TRUE;
    }
    
  7. Alpha Cannel でブレンドする WipeAlph() 関数です。
    hWBmpDC の明度をα値と rate に従ったレベルに下げて hBmpDC に格納します。
    // hWBmpDC の明度をα値と rate に従ったレベルに下げて hBmpDC に格納する
    HRESULT  ALPHA32::WipeAlph(float rate)
    {   LONG    dx,dy;
        WORD    r,g,b,a;
        float   rt;
    
        if (AlphFlg==FALSE)
        {   BitBlt(hBmpDC,0,0,Width,Height,hWBmpDC,0,0,SRCCOPY);
            return FALSE;
        }
        if (hWBmpDC==NULL)  return FALSE;
        if (hBmpDC==NULL)   return FALSE;
        // 明度を rate レベルに下げる
        for(dy=0; dy<Height; dy++)
            for(dx=0; dx<Width; dx++)
            {   b = (WORD)WData[(dy*Width+dx)*4];
                g = (WORD)WData[(dy*Width+dx)*4+1];
                r = (WORD)WData[(dy*Width+dx)*4+2];
                a = (WORD)WData[(dy*Width+dx)*4+3];
                rt= (float)a/255.0f*rate; 
                Data[(dy*Width+dx)*4]   = (BYTE)(b*rt);
                Data[(dy*Width+dx)*4+1] = (BYTE)(g*rt);
                Data[(dy*Width+dx)*4+2] = (BYTE)(r*rt);
            }
        return TRUE;
    }
    
  8. Alpha Cannel 付きの 32bit 画像ファイルを作成する PutBmp32() 関数です。
    ピクセルデータの並び(WData)が定義されているので、ヘッダー情報を頭に付加して書き出すだけです。
    // BMP32(hWBmpDC) アルファチャンネル画像をファイルに保存する
    HRESULT  ALPHA32::PutBmp32(LPSTR fname)
    {   HANDLE  hFile;
        DWORD   dwBytes,len;
        BITMAP  bm;
        static  BITMAPFILEHEADER    g_Bf = {  0x4d42, 0, 0, 0, 0x36  };
        static  BITMAPINFOHEADER    g_Bi = {  0x28, 0, 0, 1, 32, 0, 0, 0, 0, 0, 0  };
    
        if (GetObject(hWBmp,sizeof(BITMAP),&bm)==0)
        {   MessageBox(NULL,"GetObject() に失敗しました", "PutBmp", MB_OK);
            return FALSE;
        }
    
        if (hWBmpDC==NULL)  return FALSE;
        hFile= CreateFile(fname,GENERIC_WRITE,0,0,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
        if (hFile==NULL)    return FALSE;
    
        len= (bm.bmWidthBytes+3) & 0xfffffffc;
        len*= bm.bmHeight;
        g_Bi.biWidth   = bm.bmWidth;
        g_Bi.biHeight  = bm.bmHeight;
        g_Bf.bfSize    = g_Bf.bfOffBits+len;
    
        WriteFile(hFile,&g_Bf,sizeof(BITMAPFILEHEADER),&dwBytes,NULL);
        WriteFile(hFile,&g_Bi,sizeof(BITMAPINFOHEADER),&dwBytes,NULL);
        WriteFile(hFile,WData,len,&dwBytes,NULL);
        CloseHandle(hFile);
        return TRUE;
    }
    

[Next Chapter ↓] Main Program
[Previous Chapter ↑] プログラムの設計

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