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

ピクチャボックスの画像をクリックして拡大、縮小表示できるようにする

注意:画像の表示方法が分からないという方は、まず「コントロールやフォームに画像を表示する」をご覧ください。

ピクチャボックスに表示した画像をマウスクリックにより、クリックした位置を中央にして、拡大(左クリックした時)、縮小(右クリックした時)できるようにしてみましょう。

ここでは、ピクチャボックスのPaintイベントでGraphics.DrawImageメソッドを使って画像を表示させることにします。ピクチャボックスがクリックされた時に(ここではMouseDownイベントを使います)、画像の表示倍率を決定し、ピクチャボックスで画像を表示する範囲を計算します。ピクチャボックスのPaintイベントハンドラでは、Graphics.DrawImageメソッドを使って実際にこの範囲に画像を表示します。

それでは実際に作成してみましょう。仕様としては、テキストボックスに画像ファイル名を入力し、ボタンをクリックすると、ピクチャボックスに画像が表示されるようにします。さらに、ピクチャボックスを左クリックすると、画像のクリックされた位置をピクチャボックスの中央にして、画像を倍に拡大して表示します。右クリックでは、逆に画像を1/2に縮小して表示します。

まずフォーム(Form1)にピクチャボックス(PictureBox1)とテキストボックス(TextBox1)とボタン(Button1)を配置します。さらに、PictureBox1のClickイベントハンドラとしてButton1_Clickを、MouseDownイベントハンドラとしてPictureBox1_MouseDownを、さらにButton1のクリックイベントハンドラとしてButton1_Clickメソッドを作成します。

これで準備は完了です。後はForm1クラスに以下のようなコードを書き込み、完成です。

VB.NET
コードを隠すコードを選択
'表示する画像
Private currentImage As Bitmap
'倍率
Private zoomRatio As Double = 1.0
'倍率変更後の画像のサイズと位置
Private drawRectangle As Rectangle

'Button1のクリックイベントハンドラ
Private Sub Button1_Click(sender As Object, e As EventArgs) _
        Handles Button1.Click
    '表示する画像を読み込む
    If Not (currentImage Is Nothing) Then
        currentImage.Dispose()
    End If
    currentImage = New Bitmap(TextBox1.Text)
    '初期化
    drawRectangle = New Rectangle(0, 0, currentImage.Width, currentImage.Height)
    zoomRatio = 1.0
    '画像を表示する
    PictureBox1.Invalidate()
End Sub

'PictureBox1のMouseDownイベントハンドラ
Private Sub PictureBox1_MouseDown(sender As Object, e As MouseEventArgs) _
        Handles PictureBox1.MouseDown
    Dim pb As PictureBox = DirectCast(sender, PictureBox)
    'クリックされた位置を画像上の位置に変換
    Dim imgPoint As New Point(CInt(Math.Round((e.X - drawRectangle.X) / zoomRatio)), _
                              CInt(Math.Round((e.Y - drawRectangle.Y) / zoomRatio)))

    '倍率を変更する
    If e.Button = MouseButtons.Left Then
        zoomRatio *= 2.0
    ElseIf e.Button = MouseButtons.Right Then
        zoomRatio *= 0.5
    End If

    '倍率変更後の画像のサイズと位置を計算する
    drawRectangle.Width = CInt(Math.Round(currentImage.Width * zoomRatio))
    drawRectangle.Height = CInt(Math.Round(currentImage.Height * zoomRatio))
    drawRectangle.X = CInt(Math.Round(pb.Width / 2.0 - imgPoint.X * zoomRatio))
    drawRectangle.Y = CInt(Math.Round(pb.Height / 2.0 - imgPoint.Y * zoomRatio))

    '画像を表示する
    PictureBox1.Invalidate()
End Sub

'PictureBox1のPaintイベントハンドラ
Private Sub PictureBox1_Paint(sender As Object, e As PaintEventArgs) _
        Handles PictureBox1.Paint
    If Not (currentImage Is Nothing) Then
        '画像を指定された位置、サイズで描画する
        e.Graphics.DrawImage(currentImage, drawRectangle)
    End If
End Sub
C#
コードを隠すコードを選択
//表示する画像
private Bitmap currentImage;
//倍率
private double zoomRatio = 1d;
//倍率変更後の画像のサイズと位置
private Rectangle drawRectangle;

//Button1のクリックイベントハンドラ
private void Button1_Click(object sender, EventArgs e)
{
    //表示する画像を読み込む
    if (currentImage != null)
    {
        currentImage.Dispose();
    }
    currentImage = new Bitmap(TextBox1.Text);
    //初期化
    drawRectangle = new Rectangle(0, 0, currentImage.Width, currentImage.Height);
    zoomRatio = 1d;
    //画像を表示する
    PictureBox1.Invalidate();
}

//PictureBox1のMouseDownイベントハンドラ
private void PictureBox1_MouseDown(object sender, MouseEventArgs e)
{
    PictureBox pb = (PictureBox)sender;
    //クリックされた位置を画像上の位置に変換
    Point imgPoint = new Point(
        (int)Math.Round((e.X - drawRectangle.X) / zoomRatio),
        (int)Math.Round((e.Y - drawRectangle.Y) / zoomRatio));

    //倍率を変更する
    if (e.Button == MouseButtons.Left)
    {
        zoomRatio *= 2d;
    }
    else if (e.Button == MouseButtons.Right)
    {
        zoomRatio *= 0.5d;
    }

    //倍率変更後の画像のサイズと位置を計算する
    drawRectangle.Width = (int)Math.Round(currentImage.Width * zoomRatio);
    drawRectangle.Height = (int)Math.Round(currentImage.Height * zoomRatio);
    drawRectangle.X = (int)Math.Round(pb.Width / 2d - imgPoint.X * zoomRatio);
    drawRectangle.Y = (int)Math.Round(pb.Height / 2d - imgPoint.Y * zoomRatio);

    //画像を表示する
    PictureBox1.Invalidate();
}

//PictureBox1のPaintイベントハンドラ
private void PictureBox1_Paint(object sender, PaintEventArgs e)
{
    if (currentImage != null)
    {
        //画像を指定された位置、サイズで描画する
        e.Graphics.DrawImage(currentImage, drawRectangle);
    }
}
  • 履歴:
  • 2013/6/23 サンプルのフィールド名を変更など。

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

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