locked
Rotate Single Bitmaps in GDI+ RRS feed

  • Question

  • Hello!

    I have searched for an answer without any success. But does anyone know how to rotate a bitmap with specified degree?

    Can i do this without using GDI+ and later use the rotated bitmap in the render process with GDI+?

    I tried to use following code;

    graphics.RotateTransform(degree)

    but that rotated the whole screen. How can i only rotate one object/bitmap?

    Thank you!

    Thursday, April 16, 2015 8:39 PM

Answers

  •  You would want to draw your image rotated using the Graphics.RotateTransform method and then call the Graphics.ResetTransform before you draw anything else.  That will make it so only the image is drawn rotated.

     For example, try this.

    Public Class Form1
        Private WithEvents Tmr As New Timer With {.Interval = 20}
        Dim Img As New Bitmap("C:\TestFolder\patches.jpg")
        Dim angle As Integer = 0
    
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            Me.DoubleBuffered = True
        End Sub
    
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            angle = 0
            Tmr.Start()
        End Sub
    
        Private Sub Tmr_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles Tmr.Tick
            If angle = 359 Then Tmr.Stop()
            angle += 1
            Me.Invalidate()
        End Sub
    
        Private Sub Form1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
            Dim pf As New PointF(CSng(Me.ClientSize.Width / 2), CSng(Me.ClientSize.Height / 2))
            e.Graphics.TranslateTransform(pf.X, pf.Y)
            e.Graphics.RotateTransform(angle)
            e.Graphics.TranslateTransform(-pf.X, -pf.Y)
            e.Graphics.DrawImage(Img, New PointF(CSng(pf.X - (Img.Width / 2)), CSng(pf.Y - (Img.Height / 2))))
    
            e.Graphics.ResetTransform() 'if you comment this out the rectangle will rotate too
    
            e.Graphics.DrawRectangle(Pens.Red, 50, 50, Me.ClientSize.Width - 101, Me.ClientSize.Height - 101)
        End Sub
    End Class


    If you say it can`t be done then i`ll try it

    • Proposed as answer by Frank L. Smith Thursday, April 16, 2015 9:46 PM
    • Edited by IronRazerz Thursday, April 16, 2015 9:48 PM
    • Marked as answer by Carl Andersson Friday, April 17, 2015 3:00 PM
    Thursday, April 16, 2015 9:44 PM

All replies

  • Hello!

    I have searched for an answer without any success. But does anyone know how to rotate a bitmap with specified degree?

    Can i do this without using GDI+ and later use the rotated bitmap in the render process with GDI+?

    I tried to use following code;

    graphics.RotateTransform(degree)

    but that rotated the whole screen. How can i only rotate one object/bitmap?

    Thank you!

    I'm not much on graphics, but you might find this MSDN document helpful, if nothing but to lead you in the right direction.

    I hope it helps. :)


    Still lost in code, just at a little higher level.

    :-)

    Thursday, April 16, 2015 9:09 PM
  •  You would want to draw your image rotated using the Graphics.RotateTransform method and then call the Graphics.ResetTransform before you draw anything else.  That will make it so only the image is drawn rotated.

     For example, try this.

    Public Class Form1
        Private WithEvents Tmr As New Timer With {.Interval = 20}
        Dim Img As New Bitmap("C:\TestFolder\patches.jpg")
        Dim angle As Integer = 0
    
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            Me.DoubleBuffered = True
        End Sub
    
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            angle = 0
            Tmr.Start()
        End Sub
    
        Private Sub Tmr_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles Tmr.Tick
            If angle = 359 Then Tmr.Stop()
            angle += 1
            Me.Invalidate()
        End Sub
    
        Private Sub Form1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
            Dim pf As New PointF(CSng(Me.ClientSize.Width / 2), CSng(Me.ClientSize.Height / 2))
            e.Graphics.TranslateTransform(pf.X, pf.Y)
            e.Graphics.RotateTransform(angle)
            e.Graphics.TranslateTransform(-pf.X, -pf.Y)
            e.Graphics.DrawImage(Img, New PointF(CSng(pf.X - (Img.Width / 2)), CSng(pf.Y - (Img.Height / 2))))
    
            e.Graphics.ResetTransform() 'if you comment this out the rectangle will rotate too
    
            e.Graphics.DrawRectangle(Pens.Red, 50, 50, Me.ClientSize.Width - 101, Me.ClientSize.Height - 101)
        End Sub
    End Class


    If you say it can`t be done then i`ll try it

    • Proposed as answer by Frank L. Smith Thursday, April 16, 2015 9:46 PM
    • Edited by IronRazerz Thursday, April 16, 2015 9:48 PM
    • Marked as answer by Carl Andersson Friday, April 17, 2015 3:00 PM
    Thursday, April 16, 2015 9:44 PM
  • First you translate the origin to the center of the image, then use rotatetransform. Then you need to move the origin back (or draw in the new coordinates), then draw.

    This example shows with and without the translation. When the origin is at the center of the image the rotation is about the image. Note how the example locates the image at x,y and draws the image half of its original size.

    When you are done rotating you can rotate back, or reset the whole transform and continue to draw. You can do any combination. Keep in mind the order you do things matters.

    Public Class Form3
        Private bmp As Bitmap = New Bitmap("c:\bitmaps\rusty.jpg")
    
        Private Sub Form3_Paint(sender As Object, e As PaintEventArgs) Handles Me.Paint
            'location of upper left of bitmap
            Dim x As Integer = 100
            Dim y As Integer = 100
    
            'size of final bitmap
            Dim w As Integer = bmp.Width / 2
            Dim h As Integer = bmp.Height / 2
    
            'location of the center of the bitmap
            Dim dx As Integer = x + (w / 2)
            Dim dy As Integer = y + (h / 2)
    
            With e.Graphics
                'show original coordinate system and origin by drawing a line to origin at upper left
                'and a rectangle where the non rotated image would be located at x,y
                .DrawLine(New Pen(Color.Red, 5), 0, 0, x, y)
                .DrawRectangle(New Pen(Color.Red, 5), x, y, w, h)
    
                'translate origin to center of image if option checked
                If CheckBox1.Checked Then .TranslateTransform(dx, dy)
    
                'rotate the local system
                .RotateTransform(-30)
    
                'return origin to upper left
                If CheckBox1.Checked Then .TranslateTransform(-dx, -dy)
    
                'draw the rotated image 
                .DrawRectangle(New Pen(Color.Blue, 5), x, y, w, h)
                .DrawImage(bmp, x, y, w, h)
    
                'draw line to current origin
                .DrawLine(New Pen(Color.Blue, 5), 0, 0, x, y)
    
                'remove the rotation and any other
                .ResetTransform()
    
                'line to original origin
                .DrawLine(New Pen(Color.Green, 5), 0, 0, x, y)
    
            End With
        End Sub
    
        Private Sub CheckBox1_CheckedChanged(sender As Object, e As EventArgs) Handles CheckBox1.CheckedChanged
            Me.Invalidate()
        End Sub
    End Class

    • Proposed as answer by IronRazerz Thursday, April 16, 2015 9:58 PM
    Thursday, April 16, 2015 9:50 PM
  • but that rotated the whole screen. How can i only rotate one object/bitmap?

    You are using the wrong graphics object.  You should show how you are creating and using your bitmap and someone can show how to get a graphics object for that bitmap.

    Thursday, April 16, 2015 9:53 PM
  • Thanks everyone!

    I understand the .RotateTransform function now!

    I have simplified the code using a sub.

        Public Shared Sub RotateObject(ByVal frame As GraphicsFrame, ByVal degree As Integer, ByVal graphic As Image, ByVal rectangle As Rectangle)
            With frame.Graphics
                .RotateTransform(degree)
                .DrawImage(graphic, rectangle)
                .ResetTransform()
            End With
        End Function

    If you are wondering what the "GraphicsFrame" is, it's a class that simplifies GDI+ drawing and can be used in gameloops...

    Link: Graphics Frame Class

    Thank you!


    Friday, April 17, 2015 3:08 PM