午後わてんのブログ

ベランダ菜園とWindows用アプリ作成(WPFとC#)

マウスクリックでPictureBoxに直線を描くテスト、VisualBasic2013

前回

gogowaten.hatenablog.com

 

 

マウスクリックでPictureBoxに直線を描く

イメージ 4
クリックしたところを頂点にして直線を描くテスト完成図
 
 
はじめにもっと単純なものから作っていく
直線を描くには座標が二つ必要
1回めのマウスクリック座標と2回めのマウスクリック座標を取得して
これを元にして直線を描いてみる

f:id:gogowaten:20191016155746p:plain

デザイン画面
用意するのはPictureBoxだけ
変更するプロパティはBorderStyle=NoneをFixedSingle
これはただ見た目のためだけ
 
 
コードはこれ

Public Class Form1
    Private PP(1) As Point(Point)頂点座標の配列
Private Sub PictureBox1_MouseClick(sender As Object, e As MouseEventArgs) Handles PictureBox1.MouseDown If e.Button = Windows.Forms.MouseButtons.Left Then '左クリックなら PP(0) = e.Location '配列の0番にクリックした座標を入れる End If End Sub
Private Sub マウスムーブ(sender As PictureBox, e As MouseEventArgs) Handles PictureBox1.MouseMove PP(1) = e.Location '配列の1番にマウスの座標を入れる Dim canvas As New Bitmap(Me.PictureBox1.Width, Me.PictureBox1.Height) Dim g As Graphics = Graphics.FromImage(canvas) g.DrawLines(Pens.Red, PP) '赤色で、配列の0番と1番の座標を結ぶ直線を描く Me.PictureBox1.Image = canvas '描いた画像をPictureBox1のImageにする g.Dispose() End Sub End Class

マウスダウンイベントで1個目の座標を変数PPの0番目に入れて
マウスムーブイベントで2個めの座標を変数PPの1番目に入れる
と同時に赤色(Pens.red)で二つの頂点座標(PP)で直線描画して
PictureBox1に画像として表示
 

f:id:gogowaten:20191016155800p:plain

画像だとこう
これを実行すると
イメージ 5
クリックした場所からマウスカーソルのところまで直線が描かれる
クリックするたびに直線の始点は変更されて
以前の直線は消える
 
描いた直線は消えてほしくないので書き加えて

Public Class Form1
    Private mp As New List(Of Point) 'すべての頂点の記録用リスト
    Private PP(1) As Point 'クリックした座標と今のマウスカーソルの座標の二つの座標記録よう
    Private LastP As Point '最後にクリックした座標記録用
    Private isDraw As Boolean = False '直線の描画の終了フラグ用

    Private Sub PictureBox1_MouseClick(sender As Object, e As MouseEventArgs) Handles PictureBox1.MouseDown
        If e.Button = Windows.Forms.MouseButtons.Left Then
            isDraw = True '描画開始フラグ
            If e.Location <> LastP Then '最後にクリックした場所と今クリックされた場所が違うなら
                LastP = e.Location '今クリックされた座標を記録
                PP(0) = e.Location '今クリックされた座標を直線の始点に記録
                mp.Add(e.Location) '今クリックされた座標をリストに追加

                'リストにある記録が2個以上なら直線を描画してPictureBox1の背景にする
                If mp.Count >= 2 Then
                    Dim canvas As New Bitmap(Me.PictureBox1.Width, Me.PictureBox1.Height)
                    Dim g As Graphics = Graphics.FromImage(canvas)
                    Dim mpp() As Point = DirectCast(mp.ToArray, Point()) 'リストを配列に変換
                    g.DrawLines(Pens.Red, mpp) '赤色で直線描画
                    Me.PictureBox1.BackgroundImage = canvas '描画した画像をPictureBox1の背景(BackgroundImage)に指定
                    g.Dispose()

                End If
            End If
        End If

    End Sub

    Private Sub ダブルクリック(sender As PictureBox, e As MouseEventArgs) Handles PictureBox1.DoubleClick
        isDraw = False 'ダブルクリックされたら描画終了
    End Sub
    Private Sub マウスムーブ(sender As PictureBox, e As MouseEventArgs) Handles PictureBox1.MouseMove
        If isDraw Then
            PP(1) = e.Location '今のマウスカーソルの画像を配列に記録
            Dim canvas As New Bitmap(Me.PictureBox1.Width, Me.PictureBox1.Height)
            Dim g As Graphics = Graphics.FromImage(canvas)
            g.DrawLines(Pens.Red, PP) '赤色で直線描画
            Me.PictureBox1.Image = canvas '描いた画像をPictureBox1の画像(Image)に指定
            g.Dispose()
        End If
    End Sub

End Class

f:id:gogowaten:20191016155818p:plain

画像だとこう、これで完成で
実行して動かしているのが一番上のアニメーションgif
 
どんどんクリックしても線が消えないのは
今までクリックした座標を変数にどんどん追加して記録していって
クリックした(クリックダウンイベント)時に描画して
出来上がった画像をPictureBox1の
背景(BackgroundImage)に指定しているから
一方、マウスを動かしている(マウスムーブイベント)時は
最後にクリックした場所から今のマウスカーソルまでの直線だけを描画していて
出来上がった画像はPictureBox1の背景ではなく画像(Image)に指定している
 
これでなんとなくわかった
これを元にしてPixtack紫陽花の図形2の線の描画にうまく取り込めるかどうか
 
実行ファイルとソース
 
関連記事
2015/01/22は1日後
2018/06/06は3年5ヶ月後
マウスクリックでCanvasに直線を描画、Line、Path、WPFC# ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
https://blogs.yahoo.co.jp/gogowaten/15537737.html