2.画像ファイルを開いて表示

JPEG , GIF ,PNG ,BMP そしてTIFFなどの画像ファイルを、GDI+で開いて表示するには次のようにします。

1.画像ファイルのパス(Unicode文字配列)を使ってImage クラスを作成
2.画像を表示するウインドウなどのデバイスコンテキストを使ってGraphics クラスを作成
3.2で作成したGraphics オブジェクトのDrawImageメソッドを使って画像を描画

 Image、Graphics クラスはGDI+で定義されているクラスです。


Imageオブジェクト作成

 Imageオブジェクトは Image(画像ファイルパス)のように画像ファイルのパスを引数にして作ることが出来ます。
 ただし引数のパスはUnicode文字列でなくてはなりません。
 実際のプログラムでは、

   Image *the_image = NULL ;
   WCHAR w_filepath[MAX_PATH] =L"";
    the_image = new Image(w_filepath) ; //(ビットマップから)Imageオブジェクト

のようになります。
 上の例では画像ファイルパスが固定されています。


Graphicsオブジェクトと画像表示

 Graphics オブジェクトはGraphics(デバイスコンテキストハンドル)のように画像を描こうとするウインドウなどの デバイスコンテキストハンドルを引数にして作成します。
 画像を表示するにはGrapics::DrawImage メソッドを使いますが、下の例で使用しているものは、

Status DrawImage(
[in] Image *image, //表示したい画像のImageオブジェクト
[in] INT x,//画像を表示する矩形の左上のx座標
[in] INT y,//画像を表示する矩形の左上のy座標
[in] INT width,//画像を表示する矩形の幅
[in] INT height//画像を表示する矩形の高さ
);
と定義されているものです。

   HDC h_dc ; //画像を描く対象デバイスコンテキスト
   UINT pic_width, pic_height ; //画像幅・高さ

   Graphics the_graph(h_dc) ; //これより前でh_dc を何らかの方法で取得しておく
    pic_width = the_image->GetWidth() ;
    pic_height = the_image->GetHeight() ;

    the_graph.DrawImage(the_image, 0 ,0 ,pic_width, pic_height);

 この例では画像を表示する矩形の大きさとして、画像と同じ幅・高さをとっています。
 画像の幅と高さはImageクラスのメソッドGetWidth とGetHeight で求めることができます。


 上の例で作成した the_image は動的変数なので、使用しなくなったらdelete で解放することを忘れないでください。

    delete the_image ;


実際のプログラム例

 以下で実際のプログラムで画像を表示する例を示します。
 前頁のプログラムでは、ウインドウ手続き関数WndProc が未定義でしたが、 そこを下の例のように定義すると一応動作するプログラムになります。

/*
      ウインドウ手続き関数
*/

LRESULT CALLBACK WndProc( HWND hWnd, UINT messg ,
                     WPARAM wParam, LPARAM lParam )

{
   static Image *the_image = NULL ;
   static UINT pic_width, pic_height ;

    switch(messg){
     case WM_CREATE://起動時に画像(固定)読み取り
      WCHAR w_filepath[MAX_PATH] =L"";
      the_image = new Image(w_filepath);//画像ファイルからイメージオブジェクト
      pic_width = the_image->GetWidth() ; pic_height = the_image->GetHeight() ;
     break ;

     case WM_PAINT:
      HDC win_dc ;
      PAINTSTRUCT pstruct;//struct for the call to BeginPaint

      win_dc = BeginPaint(h_pWnd, &pstruct ); //prepare window for painting
       Graphics the_graph(win_dc );
       the_graph.DrawImage(the_image, 0 ,0 ,pic_width, pic_height);
     break ;

     case WM_DESTROY: //動的オブジェクトの破棄など
      delete the_image ;
      PostQuitMessage( 0 );
     break;

    }

}

 上のプログラムではウインドウの初期化処理( WM_CREATE)のときに、画像ファイルからImageオブジェクトを作成し、 ウインドウ画面が書き直される時(WM_PAINT)にウインドウに直接画像を描画しています。


 上の例では、Imageオブジェクトを使って直接ウインドウに画像を出力していますが、仮想ウインドウを作成して そこに一度だけ出力し、ウインドウがアップデートされる時、仮想ウインドウからウインドウに画像を転送する方法が よくもちいられます。
 下のプログラムは仮想ウインドウをつかった例です。
 ただし下の例では、ウインドウが初期化されるときに、Imageオブジェクト、仮想ウインドウの作成と画像の仮想ウインドウへの 出力をしています。
 そのため、このままだと別の画像を表示したりできません。

LRESULT CALLBACK WndProc( HWND hWnd, UINT messg ,
                     WPARAM wParam, LPARAM lParam )

{
   static Image *the_image = NULL ;
   static UINT pic_width, pic_height ;
   static HDC virmem_dc = NULL ;
   static HBITMAP vir_hbmp = NULL ;

    switch(messg){
     case WM_CREATE:
      WCHAR w_filepath[MAX_PATH] =L"";
      the_image = new Image(w_filepath);//(ビットマップから)イメージオブジェクト
      pic_width = the_image->GetWidth() ;
      pic_height = the_image->GetHeight() ;

      //仮想ウインドウ作成
      HBRUSH hbrush ;
      HDC hwin_dc ;
      hwin_dc =GetDC(hWnd) ;
       virmem_dc =CreateCompatibleDC( hwin_dc ) ;
       vir_hbmp =CreateCompatibleBitmap(hwin_dc ,pic_width ,pic_height ) ;
       SelectObject(virmem_dc ,vir_hbmp ) ;
       hbrush =(HBRUSH)GetStockObject(the_brush ) ;
       SelectObject(virmem_dc ,hbrush ) ;
       PatBlt(virmem_dc ,0,0, pic_width , pic_height ,PATCOPY ) ;//設定ブラシで塗りつぶし
      ReleaseDC( hWnd ,hwin_dc ) ;

      //仮想ウインドウにファイル内容(画像)を書く

     break ;

     case WM_PAINT:
      HDC win_dc ;
      PAINTSTRUCT pstruct;//struct for the call to BeginPaint

      win_dc = BeginPaint(hWnd, &pstruct ); //prepare window for painting
       BitBlt( win_dc , 0 , 0 ,pic_width, pic_height , virmem_dc ,0,0 ,SRC_COPY ) ;//転送
      EndPaint(hWnd, &pstruct );// stop painting

     break ;

     case WM_DESTROY:
      //後始末 、動的オブジェクトの破棄など
      if( virmem_dc != NULL )
       DeleteDC( virmem_dc ) ;

      if( vir_hbmp != NULL )
       DeleteObject( vir_hbmp ) ;

      if( the_image != NULL )
       delete the_image ;//Imageオブジェクト解放

      PostQuitMessage( 0 );
     break ;

    }

}

準備に戻る