DOBON.NET プログラミング道: .NET Framework, VB.NET, C#, Visual Basic, Visual Studio, インストーラ, ...

DOBON.NET

画像ファイルを表示する

ピクチャボックスに画像を表示する最も簡単な方法は「ピクチャボックスに簡単に画像を表示する」で紹介しましたが、この方法は融通が利かず、使用できるケースは限られます。

画像を描画する最も一般的な方法は、GraphicsクラスのDrawImageメソッドを使う方法です。例えばピクチャボックスに画像を表示するときは、そのピクチャボックスのGraphicsオブジェクトを取得し、DrawImageメソッドで画像を描画すればよいのです。

それではGraphicsオブジェクトを取得するにはどのようにすればよいのでしょうか?よく使われる方法は次の2つです。

  1. Paintイベントハンドラ等のパラメータから取得する。
  2. Control.CreateGraphicsメソッドにより取得する。

Paintイベントで描画する方法

まずは1番目の方法から説明します。コントロールやフォームに画像を表示するための最も一般的な方法は、Paintイベントで描画することでしょう。Paintイベントハンドラでは、パラメータとして渡されるPaintEventArgsオブジェクトのGraphicsプロパティによりGraphicsオブジェクトを取得できますので、これを使って描画します。

次の例では、画像ファイルをBitmapオブジェクト(System.Drawing名前空間)に読み込み、その画像をピクチャボックス(PictureBox1)のPaintイベントハンドラで描画することにより、画像を表示しています。

[VB.NET]
'Bitmapオブジェクトの作成(画像ファイルを読み込む)
Private _bmp As New Bitmap("C:\Blue hills.jpg")
'または、次のようにも出来る
'Dim _bmp As Image = Image.FromFile("C:\Blue hills.jpg")

'PictureBox1のイベントハンドラ
Private Sub PictureBox1_Paint(ByVal sender As Object, _
        ByVal e As System.Windows.Forms.PaintEventArgs) _
        Handles PictureBox1.Paint
    'Paintイベントハンドラで画像を表示する
    e.Graphics.DrawImage(_bmp, 0, 0, _bmp.Width, _bmp.Height)
End Sub
[C#]
//Bitmapオブジェクトの作成(画像ファイルを読み込む)
Bitmap _bmp = new Bitmap(@"C:\Blue hills.jpg");
//または、次のようにも出来る
//Image _bmp = Image.FromFile(@"C:\Blue hills.jpg");

//PictureBox1のイベントハンドラ
private void PictureBox1_Paint(object sender,
    System.Windows.Forms.PaintEventArgs e)
{
    //Paintイベントハンドラで画像を表示する
    e.Graphics.DrawImage(_bmp, 0, 0, _bmp.Width, _bmp.Height);
}

注意:上記のC#のコードは、このままコピーしただけでは動きません。イベントハンドラをイベントに関連付ける必要があります。この方法については、こちらで説明しています。

補足:フォームに画像を表示させる場合は、上記と同様にPaintイベントハンドラを使う方法以外に、OnPaintメソッドをオーバーライドし、その内で画像を描画する方法も良く使われます。

補足:メタファイルを表示するには、Bitmapクラスの代わりにMetafileクラスを使います。使い方は、ほぼ同じです。

Paintイベントを発生させる方法

表示している画像を変更した場合は、新しい画像を表示するためにPaintイベントを呼び出す必要があります。コントロールのPaintイベントを発生させるには、コントロールのInvalidateメソッド(または、Refreshメソッド)を呼び出します。例えばピクチャボックスのリサイズによって画像を描きなおす必要があるときは、次のようにピクチャボックスのResizeイベントハンドラでInvalidateメソッドを呼び出し、Paintイベントを発生させます。

[VB.NET]
Private  Sub PictureBox1_Resize(ByVal sender As Object, _
        ByVal e As System.EventArgs) _
        Handles PictureBox1.Resize
    CType(sender, PictureBox).Invalidate()
End Sub
[C#]
private void PictureBox1_Resize(object sender, System.EventArgs e)
{
    ((PictureBox) sender).Invalidate();
}

なお、これらのメソッドに関しては、こちらで詳しく説明しています。

CreateGraphicsメソッドを使う方法

Paintイベントによる方法が使えない場合は、こちらの方法となります。

コントロールやフォームに画像を描画するために使用するGraphicsオブジェクトは、Control.CreateGraphicsメソッドにより取得できます。CreateGraphicsメソッドにより取得したGraphicsオブジェクトは、使用後Disposeメソッドにより破棄する必要があります。

次のコードはその例として、ピクチャボックス(PictureBox1)の座標(60, 10)に画像を表示させています。

[VB.NET]
Dim _bmp As Bitmap =  New Bitmap("C:\Blue hills.jpg")

'PictureBox1のGraphicsオブジェクトの作成
Dim g As Graphics =  PictureBox1.CreateGraphics() 
'画像の描画
g.DrawImage(_bmp, 60, 10, _bmp.Width, _bmp.Height)
'BitmapとGraphicsオブジェクトを破棄
_bmp.Dispose()
g.Dispose()
[C#]
Bitmap _bmp = new Bitmap(@"C:\Blue hills.jpg");

//PictureBox1のGraphicsオブジェクトの作成
Graphics  g= PictureBox1.CreateGraphics();
//画像の描画
g.DrawImage(_bmp, 60, 10, _bmp.Width, _bmp.Height);
//BitmapとGraphicsオブジェクトを破棄
_bmp.Dispose();
g.Dispose();

このような方法で描画された画像は、他のウィンドウの後ろに隠れたりすることにより、簡単に消えてしまいます。これを解決するには、先に紹介したPaintイベントで描画する方法をお使いください。

注意:PictureBox1のPaintイベントハンドラに上記のようなコードを記述しないようにしてください。正しく表示されなくなります。

自動スケーリングについて

ここからは補足です。ここで紹介した例では、DrawImageメソッドに画像を表示する座標と大きさを指定しています。大きさを指定せずに座標だけを指定することもできますが、これではGDI+の自動スケーリングが働き、意図せぬ大きさで描画されたり、パフォーマンスが落ちたりする可能性があります。これを回避するためには、上記のコードのように元の画像の大きさを指定してDrawImageメソッドで描画するか、DrawImageメソッドの代わりにDrawImageUnscaledメソッドを使用します。自動スケーリングについて詳しくは自動スケーリングの解除によるパフォーマンスの向上をご覧ください。

  • 履歴:
  • 2006/11/22 1番目と2番目の方法の順序を入れ替えた。

注意:この記事では、基本的な事柄の説明が省略されているかもしれません。初心者の方は、特に以下の点にご注意ください。

  • このサイトで紹介されているコードの多くは、例外処理が省略されています。例外処理については、こちらをご覧ください。
  • イベントハンドラの意味が分からない、C#のコードをそのまま書いても動かないという方は、こちらをご覧ください。