Rank: Advanced Member
Groups: Member, Administration Joined: 8/2/2003(UTC) Posts: 876
Thanks: 2 times Was thanked: 27 time(s) in 27 post(s)
|
Hi Raghavendra, According to our email correspondence, the only problem you need to solve is to draw rubberband polygon at the BitmapViewer control. I have written a code sample for this at last weekends. Please find it below. I have tried to comment it in details. But if anything is still unclear here, please post a message here. Code:Option Base 0
' A Graphics object which draws the polygon
Private objGraphics As Graphics
' An array of points which represents the polygon
Private arrPolygon() As Long
' A number of point which is currently being dragged. If no current point selected, it equals to the NotInitialized
Private currentPoint As Long
' A value which specifies an "epsilon neighborhood" of the anchor point (i.e. the distance around the point
' which is considered as this point when hit test is applied)
Const Epsilon As Long = 6
' A value which specifies that the numeric value is not initialized (e.g. the index of the
' current point when no point selected). It should be negative (invalid) so that it would
' not be confused with valid values.
Const NotInitialized = -100
Private Sub DrawPolygon()
' Since our polygon is stored in coordinates relatively the image, we need to recalculate these coordinates
' relatively the BitmapViewer control.
Dim tempPolygon() As Long
ReDim tempPolygon(UBound(arrPolygon))
For I = 0 To UBound(arrPolygon) Step 2
tempPolygon(I) = BitmapViewer1.BitmapToControlXCoord(arrPolygon(I))
tempPolygon(I + 1) = BitmapViewer1.BitmapToControlYCoord(arrPolygon(I + 1))
Next I
' Polygon requires at least four points, that's why if user clicked less points, skip this line.
If UBound(tempPolygon) - LBound(tempPolygon) + 1 >= 8 Then
' Set drawing settings for the polygon
objGraphics.Brush.PrimaryColor = ColorBlack
objGraphics.Brush.IsBackgroundTransparent = True
objGraphics.Brush.Type = BrushTypeHatch
objGraphics.Brush.HatchStyle = HatchStyleBackwardDiagonal
' Draw a filled and outlined polygon
objGraphics.DrawPolygon tempPolygon, True, True
End If
' Draw anchor points
For I = LBound(tempPolygon) To UBound(tempPolygon) Step 2
' Set drawing settins for the anchor point.
objGraphics.Brush.PrimaryColor = ColorRed
objGraphics.Brush.Type = BrushTypeSolid
' Draw an anchor point
objGraphics.DrawRectangle tempPolygon(I) - Epsilon / 2, tempPolygon(I + 1) - Epsilon / 2, Epsilon, Epsilon, True
Next
End Sub
' This function tests whether a point with specified coordinates is already
' placed to the polygon. If yes, it returns the index of this point (i.e. the index
' of X coordinate of this point). Otherwise NotInitialized value is used.
Private Function HitTest(x As Long, y As Long) As Long
For I = LBound(arrPolygon) To UBound(arrPolygon) Step 2
' Since it is very hard to hit the exact pixel which specifies the coordinate
' of the polygon vertex, we define an "epsilon neighborhood" for this point.
' In other words if the selected coordinates will be as close to this point as
' a number of pixels specified as Epsilon, the function will say "OK".
If Abs(arrPolygon(I) - x) < Epsilon And Abs(arrPolygon(I + 1) - y) < Epsilon Then
HitTest = I
Exit Function
End If
Next
' Not found
HitTest = NotInitialized
End Function
Private Sub BitmapViewer1_DoubleBufferPaint(ByVal Hdc As stdole.OLE_HANDLE)
If UBound(arrPolygon) > 0 Then
objGraphics.Hdc = Hdc
DrawPolygon
End If
End Sub
Private Sub BitmapViewer1_ImageMouseDown(ByVal button As Long, ByVal shift As Long, ByVal x As Long, ByVal y As Long)
' Determine if some point has been selected.
currentPoint = HitTest(x, y)
' If not, it means that the user wants to add new one.
If currentPoint = NotInitialized Then
' A number of elements in the arrPolygon array. The number of points is count/2.
Dim count As Long
count = UBound(arrPolygon) - LBound(arrPolygon) + 1
' I did not find an easy way to handle the situation when no elements are available
' in array. That's why I had to do a trick - in Form_Load I create a single point and
' set their coordinates to NotInitialized. When the user add the first point, I just
' rewrite these coordinates, and next points are added in a common way (using Redim statement).
If count = 2 And arrPolygon(0) = NotInitialized And arrPolygon(1) = NotInitialized Then
arrPolygon(0) = x
arrPolygon(1) = y
Else
ReDim Preserve arrPolygon(count + 1)
arrPolygon(count) = x
arrPolygon(count + 1) = y
End If
' Redraw the polygon at the control.
BitmapViewer1.FastRefresh
End If
End Sub
Private Sub BitmapViewer1_ImageMouseMove(ByVal button As Long, ByVal shift As Long, ByVal x As Long, ByVal y As Long)
' If the current point is selected, move this point.
If currentPoint <> NotInitialized Then
arrPolygon(currentPoint) = x
arrPolygon(currentPoint + 1) = y
BitmapViewer1.FastRefresh
End If
' Display current coordinates
Label1.Caption = "X :" & x & " Y: " & y
End Sub
Private Sub BitmapViewer1_ImageMouseUp(ByVal button As Long, ByVal shift As Long, ByVal x As Long, ByVal y As Long)
' When the mouse button is released, we need to "detach" from the current point.
currentPoint = NotInitialized
End Sub
' Initialization is made there.
Private Sub Form_Load()
' Here you can load the bitmap from file, etc. I am just creating 640x480 image for brevity.
BitmapViewer1.Bitmap.CreateNew 640, 480
' Create and initialize a Graphics object. Note, I am using GDI engine (rather than GDI+)
' to provide higher performance. But if you want to draw semitransparent polygon, etc., you
' should use GDI+.
Set objGraphics = New Graphics
objGraphics.Engine = DrawingEngineGdi
' Initialize polygon. See comments in BitmapViewer1_ImageMouseDown function
' for more details.
ReDim arrPolygon(1)
arrPolygon(0) = NotInitialized
arrPolygon(1) = NotInitialized
' No current point selected.
currentPoint = NotInitialized
End Sub
Edited by user Monday, December 24, 2007 3:55:35 PM(UTC)
| Reason: Not specified
|