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

PictureBoxを使って、非同期的に画像を読み込み、表示する

注意:ここで紹介する方法は、.NET Framework 2.0以降でのみ有効です。

ここではPictureBox.ImageLocationプロパティや、Load、LoadAsyncメソッドを使って画像を表示する方法を説明します。これらのプロパティやメソッドは.NET Framework 2.0から追加されたため、.NET Framework 1.1以前では使用できません。

PictureBoxコントロールに簡単に画像を表示する」で紹介したように、次のようなコードで画像を読み込んで表示することができます。

VB.NET
コードを隠すコードを選択
'PictureBox1に"C:\test.bmp"を表示する
PictureBox1.ImageLocation = "C:\test.bmp"
C#
コードを隠すコードを選択
//PictureBox1に"C:\test.bmp"を表示する
PictureBox1.ImageLocation = @"C:\test.bmp";

実はこのようにPictureBox.ImageLocationプロパティで画像を読み込んだとき、デフォルトでは、非同期的に処理されます。つまり、画像が読み込まれて表示されるのを待たずに、ImageLocationプロパティの処理が終了し、それ以降の処理が実行されます。

同期的に画像を読み込んで表示するには、PictureBox.WaitOnLoadプロパティをtrueにします。同期的に画像を読み込むと、画像を読み込んで表示するまではそれ以降の処理はブロックされ、フォームがフリーズしたようになります。

同期的に画像を読み込んで表示するには、PictureBox.Loadメソッドを使うこともできます。この場合はWaitOnLoadに関係なく、同期的に読み込みます。

また、非同期的に読み込んで表示するには、PictureBox.LoadAsyncメソッドを使うこともできます。この場合はWaitOnLoadがfalseでなければ、非同期となりません。

LoadやLoadAsyncメソッドを呼び出した時は、その時に指定した画像ファイルのパスがImageLocationプロパティに設定されます。

以下に示す例では、LoadAsyncメソッドを使って画像を非同期的に読み込んで表示しています。このコードはフォームクラスに書かれており、フォームには1つのPictureBoxコントロール(PictureBox1)と2つのButtonコントロール(Button1とButton2)が配置されているものとします。Button1をクリックすると画像(http://localhost/test.jpg)の読み込みを開始し、Button2をクリックすると、途中でキャンセルできます。さらに、LoadProgressChangedイベントを使ってどれだけ読み込んだかをフォームのタイトルバーに表示し、LoadCompletedイベントを使って画像の読み込みが終了したことを知らせています。

VB.NET
コードを隠すコードを選択
'Button1のClickイベントハンドラ
Private Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) _
        Handles Button1.Click
    '非同期的に画像を読み込んで表示する
    PictureBox1.WaitOnLoad = False
    PictureBox1.LoadAsync("http://localhost/test.jpg")
End Sub

'Button2のClickイベントハンドラ
Private Sub Button2_Click(ByVal sender As Object, ByVal e As EventArgs) _
        Handles Button2.Click
    '非同期読み込みをキャンセルする
    PictureBox1.CancelAsync()
End Sub

'PictureBox1のLoadProgressChangedイベントハンドラ
Private Sub PictureBox1_LoadProgressChanged(ByVal sender As Object, _
        ByVal e As System.ComponentModel.ProgressChangedEventArgs) _
        Handles PictureBox1.LoadProgressChanged
    Me.Text = String.Format("{0}% 読み込みました", e.ProgressPercentage)
End Sub

'PictureBox1のLoadCompletedイベントハンドラ
Private Sub PictureBox1_LoadCompleted(ByVal sender As Object, _
        ByVal e As System.ComponentModel.AsyncCompletedEventArgs) _
        Handles PictureBox1.LoadCompleted
    If e.Cancelled Then
        Me.Text = "キャンセルされました"
    Else If Not (e.Error Is Nothing) Then
        Me.Text = "エラーが発生しました:" + e.Error.Message
    Else
        Me.Text = "読み込みが完了しました"
    End If
End Sub
C#
コードを隠すコードを選択
//Button1のClickイベントハンドラ
private void Button1_Click(object sender, EventArgs e)
{
    //非同期的に画像を読み込んで表示する
    PictureBox1.WaitOnLoad = false;
    PictureBox1.LoadAsync("http://localhost/test.jpg");
}

//Button2のClickイベントハンドラ
private void Button2_Click(object sender, EventArgs e)
{
    //非同期読み込みをキャンセルする
    PictureBox1.CancelAsync();
}

//PictureBox1のLoadProgressChangedイベントハンドラ
private void PictureBox1_LoadProgressChanged(object sender, ProgressChangedEventArgs e)
{
    this.Text = string.Format("{0}% 読み込みました", e.ProgressPercentage);
}

//PictureBox1のLoadCompletedイベントハンドラ
private void PictureBox1_LoadCompleted(object sender, AsyncCompletedEventArgs e)
{
    if (e.Cancelled)
    {
        this.Text = "キャンセルされました";
    }
    else if (e.Error != null)
    {
        this.Text = "エラーが発生しました:" + e.Error.Message;
    }
    else
    {
        this.Text = "読み込みが完了しました";
    }
}

画像が読み込めなかったときに表示する画像を指定する

PictureBox.ImageLocationプロパティやLoad、LoadAsyncメソッドで画像の読み込みに失敗した時に表示する画像を、ErrorImageプロパティに指定することができます。ErrorImageプロパティに何も指定していなければ、画像の読む込み失敗時に表示される画像は、四角にXのマーク(下図)になります。

ErrorImageプロパティ

補足:.NET Framework 1.1以前で同じ事を行うには、画像をImage.FromFileで読み込み、失敗したらエラー用の画像を表示するようにすればよいでしょう。

この画像は、PictureBox.SizeModeプロパティにかかわらず、ピクチャボックスの中央に表示されます。

VB.NET
コードを隠すコードを選択
'エラー時に表示する画像を指定
PictureBox1.ErrorImage = Image.FromFile("C:\err.gif")
C#
コードを隠すコードを選択
//エラー時に表示する画像を指定
PictureBox1.ErrorImage = Image.FromFile(@"C:\err.gif");

画像を読み込み中に表示する画像を指定する

上記のように非同期的に画像を読み込でいる場合は、画像を読み込んでいる間、別の画像を表示させておくことができます。この画像は、PictureBox.InitialImageプロパティで指定します。何も指定していないときは、下図のような画像が表示されます。

InitialImageプロパティ

この画像もPictureBox.SizeModeプロパティにかかわらず、ピクチャボックスの中央に表示されます。

  • 履歴:
  • 2012/7/27 LoadAsyncメソッドを使ったコードを修正。
  • 2013/9/1 LoadAsyncメソッドの説明で、「WaitOnLoadがtrue」となっていたのを修正。

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

  • イベントハンドラの意味が分からない、C#のコードをそのまま書いても動かないという方は、こちらをご覧ください。
  • Windows Vista以降でUACが有効になっていると、ファイルへの書き込みに失敗する可能性があります。詳しくは、こちらをご覧ください。
  • .NET Tipsをご利用いただく際は、注意事項をお守りください。