15,916,215 members
2.00/5 (1 vote)
See more:
I want to rotate an image in a picturebox then add it to a panel (so I can put multiple images on the panel). The problem is it always makes the image (area around the image) larger.

My code I found to rotate

VB
```Dim bm_in As New Bitmap(PictureBox1.Image)

' Make an array of points defining the
' image's corners.
Dim wid As Single = bm_in.Width
Dim hgt As Single = bm_in.Height
Dim corners As Point() = { _
New Point(0, 0), _
New Point(wid, 0), _
New Point(0, hgt), _
New Point(wid, hgt)}

' Translate to center the bounding box at the origin.
Dim cx As Single = wid / 2
Dim cy As Single = hgt / 2
Dim i As Long
For i = 0 To 3
corners(i).X -= cx
corners(i).Y -= cy
Next i

' Rotate.
Dim theta As Single = Single.Parse(5) * PI / 180.0
Dim sin_theta As Single = Sin(theta)
Dim cos_theta As Single = Cos(theta)
Dim X As Single
Dim Y As Single
For i = 0 To 3
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 so X >= 0 and Y >=0 for all corners.
Dim xmin As Single = corners(0).X
Dim ymin As Single = corners(0).Y
For i = 1 To 3
If xmin > corners(i).X Then xmin = corners(i).X
If ymin > corners(i).Y Then ymin = corners(i).Y
Next i
For i = 0 To 3
corners(i).X -= xmin
corners(i).Y -= ymin
Next i

' Create an output Bitmap and Graphics object.
Dim bm_out As New Bitmap(CInt(-2 * xmin), CInt(-2 * ymin))
Dim gr_out As Graphics = Graphics.FromImage(bm_out)

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

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

' Display the result.
PictureBox1.Image = bm_out```
Posted

## Solution 1

Use a `Panel` instead of a `PictureBox`, and then add images to the `Panel`. Override the panel's `Paint` event handler, and use the `e.Graphics.RotateTransform` method to rotate the image.

wiswalld 17-Dec-11 11:30am
I am not sure how to use the e.Graphics.RotateTransform method. I have been researching it all morning but all examples add some text or lines. Kinda new at this graphics stuff.
wiswalld 17-Dec-11 11:31am
and do you mean use a panel as the source because now I use a picture box as the source then rotate then add the image to the panel
Sergey Alexandrovich Kryukov 18-Dec-11 14:50pm
No! You don't need a picture box.
--SA
Sergey Alexandrovich Kryukov 18-Dec-11 14:54pm
--SA
Sergey Alexandrovich Kryukov 18-Dec-11 14:49pm
That would work, but it's even better to use a class based on Control. Panel probably does not add any useful functionality. Inheritance is needed anyway, to access protected SetStyle. My 4.
--SA

## Solution 2

This is another example of misuse of `PictureBox`. This class does not add any functionality, will only add hassles and unwanted resource consumption.
I tried to explain what to do in my past solution How do I clear a panel from old drawing[^].

What kind of playful method is Paint? (DataGridViewImageCell.Paint(...))[^],
Drawing Lines between mdi child forms[^],
capture the drawing on a panel[^].

—SA

wiswalld 20-Dec-11 12:33pm
Here is what I have come up with but I cannot figure out how to use the bitmap as the sourcePB

Public Class Form1
Dim imagetwo As Bitmap
Dim angle As Integer = 0

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
SetStyle(ControlStyles.DoubleBuffer, True)
SetStyle(ControlStyles.AllPaintingInWmPaint, True)
'imagetwo = New Bitmap("C:\Documents and Settings\wiswalld\My Documents\DEP Police Patch.bmp")
imagetwo = New Bitmap(PictureBox1.Image)
imagetwo.MakeTransparent(Color.Black)
'gameloop.start()

WirePBs(Me)
For Each ctl As Control In Me.Controls
If TypeOf ctl Is PictureBox Then
End If
Next
End Sub

Private Sub gameloop_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles gameloop.Tick
angle += 5
Me.Refresh()
End Sub

Private Sub Form1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
e.Graphics.TranslateTransform(90, 90)
e.Graphics.RotateTransform(angle)
e.Graphics.DrawImage(imagetwo, -50, -50, 100, 100)
e.Graphics.ResetTransform()
End Sub

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Me.angle += 5
Me.Refresh()
End Sub

Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Me.PictureBox1.Image = New Bitmap("C:\Documents and Settings\wiswalld\My Documents\DEP Police Patch.bmp")
imagetwo = New Bitmap(PictureBox1.Image)
imagetwo.MakeTransparent(Color.Black)
End Sub

Private Sub Button1_MouseWheel(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Button1.MouseWheel
Me.angle += 5
Me.Refresh()
End Sub

Private pb As PictureBox = Nothing
Dim currentPicBox As PictureBox
Private targetPB As PictureBox
Private Sub WirePBs(ByVal cont As Control)
For Each ctl As Control In cont.Controls
If TypeOf ctl Is PictureBox Then
Dim pb As PictureBox = DirectCast(ctl, PictureBox)
ElseIf ctl.HasChildren Then
WirePBs(ctl)
End If
Next
End Sub
Private startX, startY As Integer

Private Sub targetPB_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
If e.Button = Windows.Forms.MouseButtons.Left Then
startX = e.X
startY = e.Y
ElseIf e.Button = Windows.Forms.MouseButtons.Right Then
targetPB = sender
End If
End Sub

Private Sub targetPB_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
If e.Button = Windows.Forms.MouseButtons.Left Then
Dim pb As PictureBox = CType(sender, PictureBox)
pb.Location = New Point(pb.Left + e.X - startX, pb.Top + e.Y - startY)
End If
End Sub

Private Sub mi_Click(ByVal sender As Object, ByVal e As System.EventArgs)
MainPanel.Controls.Remove(targetPB)
End Sub

Private Sub sourcePB_Click(ByVal sender As Object, ByVal e As System.EventArgs)
Dim pb As New PictureBox
pb.SizeMode = PictureBoxSizeMode.AutoSize
'pb.Image = CType(sender, PictureBox).Image
pb.Image = imagetwo
pb.Location = New Point(MainPanel.Width / 2 - pb.Width / 2, MainPanel.Height / 2 - pb.Height / 2)
wiswalld 20-Dec-11 12:34pm
I took out some stuff I had thrown in there

Public Class Form1
Dim imagetwo As Bitmap
Dim angle As Integer = 0

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
SetStyle(ControlStyles.DoubleBuffer, True)
SetStyle(ControlStyles.AllPaintingInWmPaint, True)
'imagetwo = New Bitmap("C:\Documents and Settings\wiswalld\My Documents\DEP Police Patch.bmp")
imagetwo = New Bitmap(PictureBox1.Image)
imagetwo.MakeTransparent(Color.Black)
'gameloop.start()

WirePBs(Me)
For Each ctl As Control In Me.Controls
If TypeOf ctl Is PictureBox Then
End If
Next
End Sub

Private Sub Form1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
e.Graphics.TranslateTransform(90, 90)
e.Graphics.RotateTransform(angle)
e.Graphics.DrawImage(imagetwo, -50, -50, 100, 100)
e.Graphics.ResetTransform()
End Sub

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Me.angle += 5
Me.Refresh()
End Sub

Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Me.PictureBox1.Image = New Bitmap("C:\Documents and Settings\wiswalld\My Documents\DEP Police Patch.bmp")
imagetwo = New Bitmap(PictureBox1.Image)
imagetwo.MakeTransparent(Color.Black)
End Sub

Private pb As PictureBox = Nothing
Dim currentPicBox As PictureBox
Private targetPB As PictureBox
Private Sub WirePBs(ByVal cont As Control)
For Each ctl As Control In cont.Controls
If TypeOf ctl Is PictureBox Then
Dim pb As PictureBox = DirectCast(ctl, PictureBox)
ElseIf ctl.HasChildren Then
WirePBs(ctl)
End If
Next
End Sub
Private startX, startY As Integer

Private Sub targetPB_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
If e.Button = Windows.Forms.MouseButtons.Left Then
startX = e.X
startY = e.Y
ElseIf e.Button = Windows.Forms.MouseButtons.Right Then
targetPB = sender
End If
End Sub

Private Sub targetPB_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
If e.Button = Windows.Forms.MouseButtons.Left Then
Dim pb As PictureBox = CType(sender, PictureBox)
pb.Location = New Point(pb.Left + e.X - startX, pb.Top + e.Y - startY)
End If
End Sub

Private Sub mi_Click(ByVal sender As Object, ByVal e As System.EventArgs)
MainPanel.Controls.Remove(targetPB)
End Sub

Private Sub sourcePB_Click(ByVal sender As Object, ByVal e As System.EventArgs)
Dim pb As New PictureBox
pb.SizeMode = PictureBoxSizeMode.AutoSize
'pb.Image = CType(sender, PictureBox).Image
pb.Image = imagetwo
pb.Location = New Point(MainPanel.Width / 2 - pb.Width / 2, MainPanel.Height / 2 - pb.Height / 2)
pb.BringToFront()
End Sub

End Class
wiswalld 21-Dec-11 9:22am
So I am able to rotate the source bitmap just fine but when I put it on the other panel it is not rotated