This is a quick little bit of code that I made up after unsuccessfully finding anyone else that had done it. What I wanted to do is take an original image, and skew it so it looked like it was going off into the distance. That gives it perspective. Obviously something like that is going to be used in this game I'm working and blogging on. More precisely, it'll be part of the map-building tools.
So you start with an image like:
and you end up with an image like:
. That's a 50% skew. The image should be half as tall at the end and is half as wide as the original. I didn't see any built-in way in GDI+ to transform the image, so I did it by brute force. Here's a reusable function to do the magic:
Private Function PerspectiveImage(ByVal sourceImage As Image, ByVal perspective As Single) As Image
Dim destImage As Image
Dim destGr As Graphics
Dim sourceSection As RectangleF
Dim destSection As RectangleF
Dim factor As Double
destImage = New Bitmap(CInt(sourceImage.Width * perspective), _
sourceImage.Height, Imaging.PixelFormat.Format32bppArgb)
destGr = Graphics.FromImage(destImage)
For i As Integer = 0 To sourceImage.Width
With sourceSection
.Height = sourceImage.Height
.Width = 1
.X = i
.Y = 0
End With
factor = perspective * (i / sourceImage.Width)
With destSection
.Height = CSng(sourceSection.Height - (sourceSection.Height * factor))
.Width = 1
.X = CSng(i * perspective)
.Y = CSng((sourceSection.Height - .Height) / 2)
End With
destGr.DrawImage(sourceImage, destSection, sourceSection, GraphicsUnit.Pixel)
Next
destGr.Dispose()
Return destImage
End Function
Basically it runs through the source image copying column by column of the image, then pasting it into the destination image at a calculated scale. You can add the value checking yourself to make sure the perspective parameter is a positive number and should be between .1 and .9. Well, you can do values greater than 1, but it's kinda weird looking. Enjoy.