Windowsフォームコントロール(フォームを含む)に画像を表示する方法はいくつかありますが(「コントロールやフォームに画像を表示する」で紹介しています)、ここではコントロールのGraphicsオブジェクトを使う方法を説明します。この方法は、.NET Framework Windowsフォームアプリケーションのグラフィックス機能の基礎であるGDI+を直接使用する方法です。
この方法で画像を表示する場合、まずコントロールのGraphicsオブジェクトを作成して、次にそのGraphicsオブジェクトを使って画像を描画するという手順になります。
コントロールのGraphicsオブジェクトを作成する方法は、通常は次の2つです。
以下、それぞれについて説明します。
コントロールのPaintイベントでは、イベントハンドラに渡されるPaintEventArgsオブジェクトのGraphicsプロパティによって、そのコントロールのGraphicsオブジェクトを取得できます。
次の例では、Panelコントロール(Panel1)にcurrentImageフィールドの画像(C:\test\1.jpg)を表示しています。
'Imports System.Drawing '画像ファイルを読み込む Private currentImage As Image = Image.FromFile("C:\test\1.jpg") 'Panel1のPaintイベントハンドラ Private Sub Panel1_Paint(ByVal sender As Object, _ ByVal e As PaintEventArgs) Handles Panel1.Paint If Not (currentImage Is Nothing) Then 'DrawImageメソッドで画像を座標(0, 0)の位置に表示する e.Graphics.DrawImage(currentImage, _ 0, 0, currentImage.Width, currentImage.Height) End If End Sub
//using System.Drawing; //画像ファイルを読み込む Image currentImage = Image.FromFile(@"C:\test\1.jpg"); //Panel1のPaintイベントハンドラ private void Panel1_Paint(object sender, PaintEventArgs e) { if (currentImage != null) { //DrawImageメソッドで画像を座標(0, 0)の位置に表示する e.Graphics.DrawImage(currentImage, 0, 0, currentImage.Width, currentImage.Height); } }
注意:上の例のようにして表示した画像ファイルはロックされ、削除できなくなります。この問題の解決法は「表示中の画像ファイルが削除できない問題の解決法」で説明しています。
この例で使用しているImage.FromFileメソッドは、画像ファイルをImageオブジェクトとして読み込む仕事をしています。これについて詳しくは、「画像ファイルを読み込み、Imageオブジェクトを作成する」で説明しています。
また、Graphics.DrawImageメソッドは、ImageオブジェクトをGraphicsオブジェクトに描画する仕事をしています。これについて詳しくは、「画像(Imageオブジェクト)を描画する」で説明しています。
ここではImageオブジェクトを描画するためにGraphics.DrawImageメソッドを使用しましたが、Graphicsクラスの他のメソッドを使えば、様々な図形や線、文字などを描画することもできます。これらについても、「長方形、多角形、楕円、円弧、扇形を描く」、「線を描く」、「曲線を描く」、「文字を描く」などで詳しく説明しています。
補足:フォームに画像を表示させる場合は、上記と同様にPaintイベントハンドラを使う方法以外に、OnPaintメソッドをオーバーライドし、その内で画像を描画する方法も良く使われます。
この方法では、表示させたい画像を新しい画像に変えたいとしても、そのままではうまく行きません。例えば上の例で、currentImageフィールドに別のImageオブジェクトを設定したとしても、すぐには新しい画像が表示されません。このような場合は、コントロールのInvalidateメソッドを呼び出して、コントロールのPaintイベントを強制的に発生させます。
以下の例では、2つの画像を入れ替えてPanel1に表示しています。currentImageフィールドに新しい画像を設定した後で「Panel1.Invalidate」を呼び出さないと、新しい画像が表示されないことをご確認ください。
'Imports System.Drawing '画像ファイルを読み込む Private images As Image() = New Image() { _ Image.FromFile("C:\test\1.jpg"), _ Image.FromFile("C:\test\2.jpg")} Private currentImage As Image = Nothing 'Panel1のイベントハンドラ Private Sub Panel1_Paint(ByVal sender As Object, _ ByVal e As PaintEventArgs) Handles Panel1.Paint If currentImage IsNot Nothing Then 'DrawImageメソッドで画像を描画する e.Graphics.DrawImage(currentImage, _ 0, 0, currentImage.Width, currentImage.Height) End If End Sub 'Button1のClickイベントハンドラ Private Sub Button1_Click(ByVal sender As Object, _ ByVal e As EventArgs) Handles Button1.Click '表示する画像を入れ替える If Not (currentImage Is images(0)) Then currentImage = images(0) Else currentImage = images(1) End If 'コントロールを再描画する。これがないと、新しい画像が表示されない。 Panel1.Invalidate() End Sub
//using System.Drawing; //画像ファイルを読み込む Image[] images = new Image[] { Image.FromFile(@"C:\test\1.jpg"), Image.FromFile(@"C:\test\2.jpg") }; Image currentImage = null; //Panel1のイベントハンドラ private void Panel1_Paint(object sender, PaintEventArgs e) { if (currentImage != null) { //DrawImageメソッドで画像を描画する e.Graphics.DrawImage(currentImage, 0, 0, currentImage.Width, currentImage.Height); } } //Button1のClickイベントハンドラ private void Button1_Click(object sender, EventArgs e) { //表示する画像を入れ替える if (currentImage != images[0]) { currentImage = images[0]; } else { currentImage = images[1]; } //コントロールを再描画する。これがないと、新しい画像が表示されない。 Panel1.Invalidate(); }
もしコントロールのサイズを変えた時に画像が正しく表示されない場合は、コントロールのResizeイベントで再描画します。
'Panel1のResizeイベントハンドラ Private Sub Panel1_Resize(ByVal sender As Object, _ ByVal e As EventArgs) Handles Panel1.Resize DirectCast(sender, Control).Invalidate() End Sub
//Panel1のResizeイベントハンドラ private void Panel1_Resize(object sender, EventArgs e) { ((Control)sender).Invalidate(); }
Invalidateメソッドに関してより詳しくは、「Refresh、Update、Invalidateメソッドの違い」をご覧ください。
Paintイベントによる方法がどうしても使えない場合は、こちらの方法です。
コントロールのGraphicsオブジェクトは、Control.CreateGraphicsメソッドで作成できます。CreateGraphicsメソッドで作成したGraphicsオブジェクトは、使用後Disposeメソッドで破棄する必要があります。
次のコードはその例として、Panelコントロール(Panel1)の座標(60, 10)に画像(C:\Blue hills.jpg)を表示しています。
'Imports System.Drawing '画像ファイルを読み込む Dim img As Image = Image.FromFile("C:\Blue hills.jpg") 'Panel1のGraphicsオブジェクトを作成 Dim g As Graphics = Panel1.CreateGraphics() '画像を描画 g.DrawImage(img, 60, 10, img.Width, img.Height) 'ImageとGraphicsオブジェクトを破棄 img.Dispose() g.Dispose()
//using System.Drawing; //画像ファイルを読み込む Image img = Image.FromFile(@"C:\Blue hills.jpg"); //Panel1のGraphicsオブジェクトを作成 Graphics g= Panel1.CreateGraphics(); //画像を描画 g.DrawImage(img, 60, 10, img.Width, img.Height); //ImageとGraphicsオブジェクトを破棄 img.Dispose(); g.Dispose();
この方法には大きな欠点があります。それは、画像を1度描画しただけで、再描画しない点です。試しに上記のコードで表示された画像の上に別のウィンドウを重ねてから、そのウィンドウをどかしてみてください。画像が消えてしまったはずです。このような再描画が必要な場面ではPaintイベントが発生しますので、Paintイベントハンドラで画像を描画していれば画像が消えることがありません。このようにCreateGraphicsメソッドを使った方法は実用性に乏しいです。
注意:Panel1のPaintイベントハンドラに上記のコードを記述しないでください。正しく表示されなくなります。
注意:この記事では、基本的な事柄の説明が省略されているかもしれません。初心者の方は、特に以下の点にご注意ください。