What's New
Q & A
Tip Jar
C# Helper...
Follow VBHelper on Twitter
MSDN Visual Basic Community
TitleSpin an image in VB .NET using DrawImage
Keywordsspin, rotate, image, VB.NET, graphics
CategoriesGraphics, VB.NET
This program is vey similar to Rotate an image in VB .NET using DrawImage. See that HowTo for an explanation of using DrawImage to rotate a picture.

This program increases the angle of rotation every time a Timer fires. In some tests, it has been able to display 90 rotated images per second. Of course your results will depend on your hardware and what other processes are running but compared to other methods on this particular computer that's very fast.

Note that the program stores several variables at a module-global level so it doesn't need to rebuild them every time it needs to rotate the image again. That makes the Timer event handler faster.

Note also that the destination Bitmap is made large enough to hold images at every angle of rotation. That way it doesn't need to resize for each rotated image.

' Copy the output bitmap from the source image.
Private m_SourceBm As Bitmap
Private m_SourceWid As Integer
Private m_SourceHgt As Integer
Private m_SourceCx As Single
Private m_SourceCy As Single
Private m_SourceCorners As PointF()

Private m_DestWid As Integer
Private m_DestHgt As Integer
Private m_DestCx As Single
Private m_DestCy As Single
Private m_DestBm As Bitmap
Private m_DestBackColor As Color

Private m_FramesDrawn As Long

' Calculate rotation values we'll need later.
Private Sub Form1_Load(ByVal sender As System.Object, ByVal _
    e As System.EventArgs) Handles MyBase.Load
    ' Initialize module-level variables.
    m_SourceBm = New Bitmap(picSource.Image)
    m_SourceWid = m_SourceBm.Width
    m_SourceHgt = m_SourceBm.Height
    m_SourceCx = m_SourceWid / 2
    m_SourceCy = m_SourceHgt / 2
    m_SourceCorners = New PointF() { _
        New PointF(0, 0), _
        New PointF(m_SourceWid, 0), _
        New PointF(0, m_SourceHgt), _
        New PointF(m_SourceWid, m_SourceHgt)}

    m_DestWid = Sqrt(m_SourceWid * m_SourceWid + _
        m_SourceHgt * m_SourceHgt)
    m_DestHgt = m_DestWid
    m_DestCx = m_DestWid / 2
    m_DestCy = m_DestHgt / 2
    m_DestBm = New Bitmap(m_DestWid, m_DestHgt)

    ' Translate the corners to center 
    ' the bounding box at the origin.
    Dim i As Long
    For i = 0 To 3
        m_SourceCorners(i).X -= m_SourceCx
        m_SourceCorners(i).Y -= m_SourceCy
    Next i

    ' Save picDest's background color.
    m_DestBackColor = picDest.BackColor
End Sub

' Start or stop spinning.
Private Sub btnStart_Click(ByVal sender As System.Object, _
    ByVal e As System.EventArgs) Handles btnStart.Click
    Static start_time As DateTime

    If tmrSpin.Enabled Then
        ' Stop spinning.
        Dim stop_time As DateTime
        stop_time = Now
        tmrSpin.Enabled = False
        btnStart.Text = "Start"

        ' Display frames per second.
        Dim elapsed_time As TimeSpan
        Dim fps As Single
        elapsed_time = stop_time.Subtract(start_time)
        fps = m_FramesDrawn / elapsed_time.TotalSeconds
        MsgBox( _
            fps.ToString("0.00") & " frames per second", _
            MsgBoxStyle.Information Or MsgBoxStyle.OKOnly, _
            "Frames Per Second")
        ' Start spinning.
        tmrSpin.Enabled = True
        btnStart.Text = "Stop"
        m_FramesDrawn = 0
        start_time = Now
    End If
End Sub

' Spin the picture a little more.
Private Sub tmrSpin_Tick(ByVal sender As System.Object, _
    ByVal e As System.EventArgs) Handles tmrSpin.Tick
    m_FramesDrawn += 1

    ' Increment the angle.
    Const dtheta = 3 * PI / 180.0
    Static theta As Single = 0
    theta += dtheta

    ' Make a local copy of the image's corners.
    Dim corners() As PointF = m_SourceCorners

    ' Drop the last corner lest we confuse DrawImage, 
    ' which expects an array of three corners.
    ReDim Preserve corners(2)

    ' Rotate.
    Dim sin_theta As Single = Sin(theta)
    Dim cos_theta As Single = Cos(theta)
    Dim X As Single
    Dim Y As Single
    Dim i As Long
    For i = 0 To 2
        X = corners(i).X
        Y = corners(i).Y
        corners(i).X = X * cos_theta + Y * sin_theta
        corners(i).Y = -X * sin_theta + Y * cos_theta
    Next i

    ' Translate to center the results in the
    ' destination image.
    For i = 0 To 2
        corners(i).X += m_DestCx
        corners(i).Y += m_DestCy
    Next i

    ' Create an output Bitmap and Graphics object.
    Dim gr_out As Graphics = Graphics.FromImage(m_DestBm)

    ' Draw the result onto the output Bitmap.
    gr_out.DrawImage(m_SourceBm, corners)

    ' Display the result.
    picDest.Image = m_DestBm
End Sub
Copyright © 1997-2010 Rocky Mountain Computer Consulting, Inc.   All rights reserved.