Having trouble drawing simple rectangle in picturebox

断了今生、忘了曾经 提交于 2020-01-06 20:38:13

问题


I have a picture box that will be showing an image. I want the user to be able to click, drag, and mouse up to a rectangle on the image. Like "I want to do something using this rectangle I drew here on this picture". If they click again, I want the previous rectangle to disappear and they start over or when I click a button to clear the highlighting rectangle they drew.

So I did find some good starting code from the msdn example about creating a zoom in rubber band rectangle that I edited a bit below, but I'm having some issues with:

       Public bHaveMouse As Boolean
Public ptOriginal As Point
Public ptLast As Point
Public rect As Rectangle
Public b_Redraw As Boolean = False


' and Normalize the points and draw the reversible frame.
Private Sub MyDrawReversibleRectangle(ByVal p1 As Point, ByVal p2 As Point)
    Try
        'clear 

        ' Convert the points to screen coordinates.
        p1 = PointToScreen(p1)
        p2 = PointToScreen(p2)
        ' Normalize the rectangle.
        If (p1.X < p2.X) Then
            rect.X = p1.X
            rect.Width = p2.X - p1.X
        Else
            rect.X = p2.X
            rect.Width = p1.X - p2.X
        End If
        If (p1.Y < p2.Y) Then
            rect.Y = p1.Y
            rect.Height = p2.Y - p1.Y
        Else
            rect.Y = p2.Y
            rect.Height = p1.Y - p2.Y
        End If

        If rect.Width > pbZoneImage.Width Then
            rect.Width = pbZoneImage.Width
        End If

        If rect.Height > pbZoneImage.Height Then
            rect.Height = pbZoneImage.Height
        End If

        ' Draw the reversible frame.
        ControlPaint.DrawReversibleFrame(rect, Color.Red, FrameStyle.Thick)
    Catch ex As Exception

    End Try

End Sub

Private Sub pbZoneImage_MouseDown(sender As Object, e As MouseEventArgs) Handles pbZoneImage.MouseDown
    If e.Button <> Windows.Forms.MouseButtons.Left Then
        Exit Sub
    End If

    Try
        ' Make a note that we "have the mouse".
        bHaveMouse = True
        ' Store the "starting point" for this rubber-band rectangle.

        If b_Redraw Then
            If (ptLast.X <> -1) Then
                '     Dim ptCurrent As Point
                'ptCurrent.X = e.X
                'ptCurrent.Y = e.Y
                MyDrawReversibleRectangle(ptOriginal, ptLast)
            End If
            ' Set flags to know that there is no "previous" line to reverse.
            ptLast.X = -1
            ptLast.Y = -1
            ptOriginal.X = -1
            ptOriginal.Y = -1
        End If

        ptOriginal.X = e.X
        ptOriginal.Y = e.Y
        ' Special value lets us know that no previous
        ' rectangle needs to be erased.
        ptLast.X = -1
        ptLast.Y = -1
    Catch ex As Exception

    End Try

End Sub

Private Sub pbZoneImage_MouseMove(sender As Object, e As MouseEventArgs) Handles pbZoneImage.MouseMove
    Dim ptCurrent As Point
    ptCurrent.X = e.X
    ptCurrent.Y = e.Y
    ' If we "have the mouse", then we draw our lines.
    If (bHaveMouse) Then
        ' If we have drawn previously, draw again in
        ' that spot to remove the lines.
        If (ptLast.X <> -1) Then
            MyDrawReversibleRectangle(ptOriginal, ptLast)
        End If
        ' Update last point.
        ptLast = ptCurrent
        ' Draw new lines.
        MyDrawReversibleRectangle(ptOriginal, ptCurrent)
    End If
End Sub

Private Sub pbZoneImage_MouseUp(sender As Object, e As MouseEventArgs) Handles pbZoneImage.MouseUp

    'Try
    '    ' Set internal flag to know we no longer "have the mouse".
    bHaveMouse = False

End Sub

My Problem: Sometimes when drawing it doesn't remove the previously drawn rectangle, or if I hover over certain buttons (like the exit button) the rectangles disappear! I want they to stay so that I can record the start and end point of the rectangle for other programs. I want them to disappear when I hit my clear rectangle button, but I feel like I am getting confused on something that should be very simple.

Another issue is I'm trying to keep the rectangle from spilling outside the picture box (Pbzoneimage). But it does, and changes color.

Where did I go wrong? Is there is a better way to draw this altogether?


回答1:


You need two bitmaps, one for the picturebox (img) and one to clear it and draw the rectangle(imgClone).

Private mouse_Down As Point
Private img As Bitmap
Private imgClone As Bitmap

Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
    img = My.Resources..... 'or you can load the image from file

    PictureBox1.Image = img 'with this every time you invalidate it draws img to picturebox

    imgClone = CType(PictureBox1.Image.Clone, Bitmap)

End Sub

Private Sub PictureBox1_MouseDown(sender As System.Object, e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseDown
    mouse_Down = e.Location
End Sub

Private Sub PictureBox1_MouseMove(sender As System.Object, e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseMove
    If e.Button = MouseButtons.Left And e.Location <> mouse_Down Then
        DrawRectangle(e.Location)
    End If
End Sub

Private Sub DrawRectangle(ByVal pnt As Point)
    Dim g As Graphics

    g = Graphics.FromImage(img)

    g.DrawImage(imgClone, 0, 0) 'we are clearing img with imgClone. imgClone contains the original image without the rectangles

    If pnt.X = mouse_Down.X Or pnt.Y = mouse_Down.Y Then
        g.DrawLine(Pens.Firebrick, mouse_Down.X, mouse_Down.Y, pnt.X, pnt.Y)

    Else
        g.DrawRectangle(Pens.Firebrick, Math.Min(mouse_Down.X, pnt.X), Math.Min(mouse_Down.Y, pnt.Y),
                    Math.Abs(mouse_Down.X - pnt.X), Math.Abs(mouse_Down.Y - pnt.Y))

    End If

    g.Dispose()

    PictureBox1.Invalidate() 'draw img to picturebox
End Sub

If you need to clear the picturebox:

Dim g As Graphics

g = Graphics.FromImage(img)
g.DrawImage(imgClone, 0, 0)

g.Dispose()

PictureBox1.Invalidate()

valter



来源:https://stackoverflow.com/questions/25854754/having-trouble-drawing-simple-rectangle-in-picturebox

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!