|
|
Title | Let the user drag points to warp an image in VB .NET using DrawImage |
Keywords | warp, drag, rotate, image, VB.NET, graphics |
Categories | Graphics, VB.NET |
|
|
The Graphics object's DrawImage method copies an image much as Visual Basic 6's PaintPicture method does. In VB .NET, however, there are 30 overloaded versions of this routine. One of them takes as parameters three points that represent where the routine should map the upper left, upper right, and lower left corners of the original image. DrawImage figures out where to put the remaining point to make the resulting figure a parallelogram. [It would have been better if it (also) let the programmer specify where to put all four points. Then you could perform the more useful mappings needed for three-dimensional graphics. Alas.]
You can use this version of DrawImage to warp an image. This program lets the user click and drag the three control corners to warp an image.
The MouseDown event handler determines whether the mouse is close enough to one of the points. If so, it records the index of the point.
When the mouse moves, if a drag is in progress, the MouseMove event handler moves the selected corner to the mouse position. It also restricrts the corner's position so it stays on the PictureBox. (Otherwise the user could drag a point off and could not click on it to drag it back.) After moving the point, MouseMove calls subroutine WarpImage to draw the warped image.
The MouseUp event handler sets m_DragCorner = -1 to indicate the move is no longer in progress.
|
|
Private Const CORNER_RADIUS As Integer = 5
Private m_BmSource As Bitmap
Private m_BmDest As Bitmap
Private m_Corners As Point()
Private m_DragCorner As Long
Private Sub Form1_Load(ByVal sender As System.Object, ByVal _
e As System.EventArgs) Handles MyBase.Load
m_BmSource = New Bitmap(picSource.Image)
m_BmDest = New Bitmap( _
CInt(m_BmSource.Width), _
CInt(m_BmSource.Height))
m_Corners = New Point() { _
New Point(0, 0), _
New Point(m_BmSource.Width, 0), _
New Point(0, m_BmSource.Height)}
m_DragCorner = -1
' Display the initial image.
WarpImage()
End Sub
' Draw the warped image.
Private Sub WarpImage()
' Make a Graphics object for the result Bitmap.
Dim gr_dest As Graphics = Graphics.FromImage(m_BmDest)
' Copy the source image into the destination bitmap.
gr_dest.Clear(picDest.BackColor)
gr_dest.DrawImage(m_BmSource, m_Corners)
' Draw the three control corners.
Dim i As Long
For i = 0 To 2
gr_dest.DrawEllipse(Pens.Black, _
m_Corners(i).X - CORNER_RADIUS, _
m_Corners(i).Y - CORNER_RADIUS, _
2 * CORNER_RADIUS, 2 * CORNER_RADIUS)
Next i
' Display the result.
picDest.Image = m_BmDest
End Sub
' Start dragging the point.
Private Sub picDest_MouseDown(ByVal sender As Object, ByVal _
e As System.Windows.Forms.MouseEventArgs) Handles _
picDest.MouseDown
Dim i As Long
' See if the mouse is near one of the corners.
For i = 0 To 2
If (Math.Abs(m_Corners(i).X - e.X) < CORNER_RADIUS) _
And _
(Math.Abs(m_Corners(i).Y - e.Y) < CORNER_RADIUS) _
_
Then
' Start dragging this corner.
m_DragCorner = i
Exit For
End If
Next i
End Sub
Private Sub picDest_MouseMove(ByVal sender As Object, ByVal _
e As System.Windows.Forms.MouseEventArgs) Handles _
picDest.MouseMove
' Make sure we are draggign a corner.
If m_DragCorner < 0 Then Exit Sub
m_Corners(m_DragCorner).X = e.X
If m_Corners(m_DragCorner).X < 0 Then
m_Corners(m_DragCorner).X = 0
ElseIf m_Corners(m_DragCorner).X > m_BmDest.Width Then
m_Corners(m_DragCorner).X = m_BmDest.Width
End If
m_Corners(m_DragCorner).Y = e.Y
If m_Corners(m_DragCorner).Y < 0 Then
m_Corners(m_DragCorner).Y = 0
ElseIf m_Corners(m_DragCorner).Y > m_BmDest.Height Then
m_Corners(m_DragCorner).Y = m_BmDest.Height
End If
WarpImage()
End Sub
' Stop dragging.
Private Sub picDest_MouseUp(ByVal sender As Object, ByVal e _
As System.Windows.Forms.MouseEventArgs) Handles _
picDest.MouseUp
m_DragCorner = -1
End Sub
|
|
|
|
|
|