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 img As Bitmap
'倍率
Private ratio As Single = 1.0F
'画像を表示させる範囲
Private imgRect As Rectangle

'Button1のクリックイベントハンドラ
Private Sub Button1_Click(ByVal sender As Object, _
    ByVal e As System.EventArgs) Handles Button1.Click
    '表示する画像を読み込む
    img = New Bitmap(TextBox1.Text)
    '初期化
    imgRect = New Rectangle(0, 0, img.Width, img.Height)
    ratio = 1.0F
    '画像を表示する
    PictureBox1.Invalidate()
End Sub

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

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

    '画像の表示範囲を計算する
    imgRect.Width = CInt(Math.Round((img.Width * ratio)))
    imgRect.Height = CInt(Math.Round((img.Height * ratio)))
    imgRect.X = CInt(Math.Round((pb.Width / 2 - imgPoint.X * ratio)))
    imgRect.Y = CInt(Math.Round((pb.Height / 2 - imgPoint.Y * ratio)))

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

'PictureBox1のPaintイベントハンドラ
Private Sub PictureBox1_Paint(ByVal sender As Object, _
    ByVal e As System.Windows.Forms.PaintEventArgs) _
    Handles PictureBox1.Paint
    If Not (img Is Nothing) Then
        '画像を指定された範囲に描画する
        e.Graphics.DrawImage(img, imgRect)
    End If
End Sub
C#
コードを隠すコードを選択
//表示する画像
private Bitmap img;
//倍率
private float ratio = 1F;
//画像を表示させる範囲
private Rectangle imgRect;

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

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

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

    //画像の表示範囲を計算する
    imgRect.Width = (int) Math.Round(img.Width * ratio);
    imgRect.Height = (int) Math.Round(img.Height * ratio);
    imgRect.X = (int) Math.Round(pb.Width / 2 - imgPoint.X * ratio);
    imgRect.Y = (int) Math.Round(pb.Height / 2 - imgPoint.Y * ratio);

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

//PictureBox1のPaintイベントハンドラ
private void PictureBox1_Paint(object sender,
    System.Windows.Forms.PaintEventArgs e)
{
    if (img != null)
    {
        //画像を指定された範囲に描画する
        e.Graphics.DrawImage(img, imgRect);
    }
}

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

  • イベントハンドラの意味が分からない、C#のコードをそのまま書いても動かないという方は、こちらをご覧ください。