I would like to include an image perspective warping option in my existing matrix calculation ("DrawTo", stated at the end of this post).
A great example using RenderSurfaceWithinCorners is in this thread.
My problem is that I can not use RenderSurfaceWithinCorners, and I am looking for a way to transform a matrix (which I use to render an image using RC6) so that the image is render as if I was using RenderSurfaceWithinCorners.
The reason I can't utilize RenderSurfaceWithinCorners is that I need to maintain image centering while compensating for x and y offsets + scaling + rotating. Therefore, I'm seeking an alternative way to transform a matrix that I use with RC6 to render images similarly to how RenderSurfaceWithinCorners would.
How could I replicate such a perspective warping in the my "DrawTo" function?
![Name: card rotation1.png
Views: 37
Size: 52.3 KB]()
This is the code that would do what I want (but which I can not use):
A great example using RenderSurfaceWithinCorners is in this thread.
My problem is that I can not use RenderSurfaceWithinCorners, and I am looking for a way to transform a matrix (which I use to render an image using RC6) so that the image is render as if I was using RenderSurfaceWithinCorners.
The reason I can't utilize RenderSurfaceWithinCorners is that I need to maintain image centering while compensating for x and y offsets + scaling + rotating. Therefore, I'm seeking an alternative way to transform a matrix that I use with RC6 to render images similarly to how RenderSurfaceWithinCorners would.
How could I replicate such a perspective warping in the my "DrawTo" function?
This is the code that would do what I want (but which I can not use):
Code:
Private Sub DrawRotated(Ang As Double, ByVal PerspectiveFactor As Double)
Dim DeltaX As Double
Dim DeltaY As Double
Dim CenterX#
Dim X1#, Y1#, X2#, Y2#
Dim X3#, Y3#, X4#, Y4#
Const kDeformY As Double = 55
DeltaX = TargetWidth * 0.5 * Cos(-Ang * 3.14159265358979)
DeltaY = kDeformY * Sin(-Ang * 3.14159265358979) * PerspectiveFactor
CenterX = PIC.ScaleWidth * 0.5
X1 = CenterX + DeltaX
Y1 = kDeformY + DeltaY
X2 = CenterX - DeltaX
Y2 = kDeformY - DeltaY
X3 = X2
Y3 = TargetHeight - kDeformY + DeltaY
X4 = X1
Y4 = TargetHeight - kDeformY - DeltaY
If Sgn(DeltaX) <> Sgn(OldDX) Then
If CurrImg = "IMG1" Then CurrImg = "IMG2" Else: CurrImg = "IMG1"
OldDX = DeltaX
End If
CC.SetSourceColor 0: CC.Paint
CC.RenderSurfaceWithinCorners CurrImg, X1, Y1, X2, Y2, X3, Y3, X4, Y4
Srf.DrawToDC PIC.hDC
DoEvents
End Sub
Code:
Public Function DrawTo(ByRef uDestCC As cCairoContext, ByVal uLeft As Long, ByVal uTop As Long) As Boolean
If m_Img Is Nothing Then
Exit Function
End If
Dim dblOffx As Double: Dim dblOffy As Double
Dim dblNewWidth As Double
Dim dblNewHeight As Double
dblNewWidth = (m_Img.Width * Me.ScaleFactorWidth)
dblNewHeight = (m_Img.Height * Me.ScaleFactorHeight)
If (dblNewWidth = 0) Or (dblNewHeight = 0) Or (m_dblAlpha < 0.05) Then
Exit Function
End If
uDestCC.Save
' Calculate offsets based on alignment and scaling
dblOffx = Me.AlignmentFactorX * (dblNewWidth / 2)
dblOffy = Me.AlignmentFactorY * (dblNewHeight / 2)
Dim dblNewX1 As Double: Dim dblNewY1 As Double
dblNewX1 = (uLeft + dblOffx)
dblNewY1 = (uTop + dblOffy)
Dim dblNewX2 As Double: Dim dblNewY2 As Double
dblNewX2 = -(m_Img.Width / 2) - (Me.CenterOffsetX / 2)
dblNewY2 = -(m_Img.Height / 2) - (Me.CenterOffsetY / 2)
m_Matrix.TranslateCoords dblNewX1, dblNewY1
m_Matrix.RotateCoordsDeg m_sngAngleDeg
m_Matrix.SkewXDeg m_dblPerspectiveFactor * Me.ScaleFactorWidth
m_Matrix.ScaleCoords Me.ScaleFactorWidth, Me.ScaleFactorHeight
m_Matrix.TranslateCoords dblNewX2, dblNewY2
' Set the final transformation
Set uDestCC.Matrix = m_Matrix
' Now draw the image with the same transformations
uDestCC.RenderSurfaceContent m_Img, 0, 0, , , , m_dblAlpha
Dim corners(3) As POINT ' Array of points for 4 corners
'Define rectangle corners using the "m_Img" surface dimensions
corners(0).x = 0: corners(0).y = 0 ' Top Left
corners(1).x = m_Img.Width: corners(1).y = 0 ' Top right
corners(2).x = 0: corners(2).y = m_Img.Height ' Bottom left
corners(3).x = m_Img.Width: corners(3).y = m_Img.Height ' Bottom right
' Transform each corner point
Dim i As Integer
For i = 0 To 3
m_Matrix.CalculatePoint corners(i).x, corners(i).y
Next
'Determine the render rect
Dim cornerTopLeft As POINT
Dim cornerBottomRight As POINT
'Start with "invalid" values
cornerTopLeft.x = 999999
cornerTopLeft.y = 999999
cornerBottomRight.x = -999999
cornerBottomRight.y = -999999
For i = 0 To 3
Dim n As POINT
n = corners(i)
'Search minimum "x" for TopLeft
If n.x < cornerTopLeft.x Then
cornerTopLeft.x = n.x
End If
'Search minimum "y" for TopLeft
If n.y < cornerTopLeft.y Then
cornerTopLeft.y = n.y
End If
'Search maximum "x" for BottomRight
If n.x > cornerBottomRight.x Then
cornerBottomRight.x = n.x
End If
'Search maximum "y" for BottomRight
If n.y > cornerBottomRight.y Then
cornerBottomRight.y = n.y
End If
Next
'store the render corners
m_TopX = cornerTopLeft.x
m_TopY = cornerTopLeft.y
m_BottomX = cornerBottomRight.x
m_BottomY = cornerBottomRight.y
' Clear the path
uDestCC.ClearPath False
m_Matrix.ResetToIdentity
uDestCC.Restore
DrawTo = True
End Function