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

ピクチャボックスで非同期的に画像を読み込み、表示する

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

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

ピクチャボックスに簡単に画像を表示する」で紹介したように、次のようなコードで画像を読み込んで表示することができます。

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

ImageLocationに"C:\test.bmp"のようなパスを指定しても大丈夫ですが、この例のように、"file:///"とする方法が推奨されています。

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

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

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

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

LoadやLoadAsyncメソッドで画像を読み込んだときは、ImageLocationプロパティがそのURLに設定されます。

以下にLoadAsyncメソッドにより、画像を非同期的に読み込んで表示する例を示します。ここではButton1をクリックすると読み込みを開始し、Button2をクリックすると、途中でキャンセルできます。さらに、LoadProgressChangedイベントにより、どれだけ読み込んだかを表示し、LoadCompletedイベントにより、画像の読み込みが終了したことを知らせています。

VB.NET
コードを隠すコードを選択
'Button1のClickイベントハンドラ
Private Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) _
        Handles Button1.Click
    'イベントハンドラの追加
    AddHandler PictureBox1.LoadProgressChanged, _
        AddressOf PictureBox1_LoadProgressChanged
    AddHandler PictureBox1.LoadCompleted, AddressOf PictureBox1_LoadCompleted

    '非同期的に画像を読み込んで表示する
    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イベントハンドラ
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イベントハンドラ
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 If
End Sub
C#
コードを隠すコードを選択
//Button1のClickイベントハンドラ
private void Button1_Click(object sender, EventArgs e)
{
    //イベントハンドラの追加
    PictureBox1.LoadProgressChanged +=
        new ProgressChangedEventHandler(PictureBox1_LoadProgressChanged);
    PictureBox1.LoadCompleted +=
        new AsyncCompletedEventHandler(PictureBox1_LoadCompleted);

    //非同期的に画像を読み込んで表示する
    PictureBox1.WaitOnLoad = false;
    PictureBox1.LoadAsync("http://localhost/test.jpg");
}

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

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

//PictureBox1のLoadCompletedイベントハンドラ
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プロパティにかかわらず、ピクチャボックスの中央に表示されます。

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

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