Answered by:
how to rotate a picture box inside a panel?

Question
Answers
-
You cant rotate a picturebox.
However you can draw a rotated image in a panel or picturebox. There are lots of possibilities.
Here is a panel class with added rotation and scaling. It fits the rotated image to the panel size.
'example using PanelEx class for rotating and scaling images to fit in a panel Public Class Form4 'declare the panelEx and add to form Private WithEvents PictureEx1 As New PanelEx With { .Parent = Me, .BackColor = Color.SteelBlue, .bgBmp = New Bitmap("c:\bitmaps\rusty.jpg"), .Rotation = -45, .ScaleFactor = 0.9} 'set scalefactor to enlarge or reduce image in panel Private Sub Form4_Resize(sender As Object, e As EventArgs) Handles Me.Resize Dim border As Integer = 20 PictureEx1.Location = New Point(border, border) PictureEx1.Size = New Size(ClientSize.Width - (2 * border), ClientSize.Height - (2 * border)) End Sub Private Sub Form6_Load(sender As Object, e As EventArgs) Handles MyBase.Load Text = "Rotate Image Example" BackColor = Color.Black AutoSize = False Form4_Resize(0, Nothing) End Sub End Class 'rotates and fits image to panel Public Class PanelEx Inherits Panel Public bgBmp As Bitmap Public Rotation As Single = 0 Public ScaleFactor As Single = 1 Public Sub New() DoubleBuffered = True End Sub Private Sub PanelEx_Resize(sender As Object, e As EventArgs) Handles Me.Resize Invalidate() End Sub Private Sub PictureboxEx_Paint(sender As Object, e As PaintEventArgs) Handles Me.Paint Dim ScreenCenter As New Point(CInt(ClientSize.Width / 2), CInt(ClientSize.Height / 2)) Dim srcRect As New Rectangle(0, 0, bgBmp.Width, bgBmp.Height) Using pth As New Drawing2D.GraphicsPath, mx As New Drawing2D.Matrix 'fit the rotated image to the picturebox 'get the rotated size by using a path bounds mx.RotateAt(Rotation, ScreenCenter) pth.AddRectangle(srcRect) pth.Transform(mx) Dim boundsRect As RectangleF = pth.GetBounds() Dim scaleRatio As Double = 1 'compare rotated size to normal, 'fit to smallest picturebox dimension If ClientSize.Width / ClientSize.Height > boundsRect.Width / boundsRect.Height Then scaleRatio = ScaleFactor * ClientSize.Height / boundsRect.Height Else scaleRatio = ScaleFactor * ClientSize.Width / boundsRect.Width End If 'new image rectangle size Dim destWidth As Integer = CInt(srcRect.Width * scaleRatio) Dim destHeight As Integer = CInt(srcRect.Height * scaleRatio) Dim destRect As New Rectangle(CInt(ScreenCenter.X - destWidth / 2), CInt(ScreenCenter.Y - destHeight / 2), destWidth, destHeight) e.Graphics.Clear(BackColor) 'rotate the drawing surface about the center of picturebox and draw e.Graphics.Transform = mx e.Graphics.DrawImage(bgBmp, destRect, srcRect, GraphicsUnit.Pixel) e.Graphics.ResetTransform() e.Graphics.DrawString("tommytwotrain", New Font("arial", 10, FontStyle.Bold), Brushes.White, 4, Height - 20) End Using End Sub End Class
- Marked as answer by Tabzee Friday, March 10, 2017 3:27 PM
All replies
-
-
I want to rotate a picture box inside a panel.
If you only want to rotate in pre-defined steps, you can rotate a bitmap using the provided rotate/flip methods. See: https://msdn.microsoft.com/en-us/library/system.drawing.image.rotateflip(v=vs.110).aspx
If you want finer control over the rotation you need to draw the image into a new bitmap using a matrix that has been rotated. See:
https://msdn.microsoft.com/en-us/library/system.drawing.drawing2d.matrix.aspx
https://msdn.microsoft.com/en-us/library/s0s56wcf.aspxNote that to use matrix rotate transform you will probably want to do an initial matrix translate transform to set the rotation point to the centre of the image.
-
I understand your question and it's wonderful when people do tricks with XAML.
Your question has led to an itch to show a piece of unforgettable work someone posted.
3D Cube spinning on a WPF window. This is in <Window />
<Window.Resources> <Storyboard x:Key="RotateStoryboard"> <Rotation3DAnimationUsingKeyFrames BeginTime="00:00:00" RepeatBehavior="Forever" Storyboard.TargetName="CubeModel" Storyboard.TargetProperty="(Model3D.Transform).(Transform3DGroup.Children)[0].(RotateTransform3D.Rotation)"> <SplineRotation3DKeyFrame KeyTime="00:00:02"> <SplineRotation3DKeyFrame.Value> <AxisAngleRotation3D Angle="180" Axis="0,1,0"/> </SplineRotation3DKeyFrame.Value> </SplineRotation3DKeyFrame> <SplineRotation3DKeyFrame KeyTime="00:00:04"> <SplineRotation3DKeyFrame.Value> <AxisAngleRotation3D Angle="359" Axis="0,1,0"/> </SplineRotation3DKeyFrame.Value> </SplineRotation3DKeyFrame> </Rotation3DAnimationUsingKeyFrames> </Storyboard> </Window.Resources>
<Window.Triggers> <EventTrigger RoutedEvent="FrameworkElement.Loaded"> <BeginStoryboard Storyboard="{StaticResource RotateStoryboard}"/> </EventTrigger> </Window.Triggers>
This next part goes in <grid />
<Viewport3D Margin="0,0,0,0" Width="200" Height="200" HorizontalAlignment="Left" VerticalAlignment="Top"> <ModelVisual3D> <ModelVisual3D.Content> <Model3DGroup x:Name="CubeModel"> <Model3DGroup.Transform> <Transform3DGroup> <RotateTransform3D /> </Transform3DGroup> </Model3DGroup.Transform> <!-- Lights --> <AmbientLight Color="Gray" /> <DirectionalLight Color="Gray" Direction="1,-2,-3" /> <DirectionalLight Color="Gray" Direction="-1,2,3" /> <GeometryModel3D> <GeometryModel3D.Geometry> <!-- Cube --> <MeshGeometry3D Positions=" -1,-1,-1 1,-1,-1 1,-1, 1 -1,-1, 1 -1,-1, 1 1,-1, 1 1, 1, 1 -1, 1, 1 1,-1, 1 1,-1,-1 1, 1,-1 1, 1, 1 1, 1, 1 1, 1,-1 -1, 1,-1 -1, 1, 1 -1,-1, 1 -1, 1, 1 -1, 1,-1 -1,-1,-1 -1,-1,-1 -1, 1,-1 1, 1,-1 1,-1,-1 " TriangleIndices=" 0 1 2 2 3 0 4 5 6 6 7 4 8 9 10 10 11 8 12 13 14 14 15 12 16 17 18 18 19 16 20 21 22 22 23 20 " /> </GeometryModel3D.Geometry> <GeometryModel3D.Material> <DiffuseMaterial Brush="Blue" /> </GeometryModel3D.Material> </GeometryModel3D> </Model3DGroup> </ModelVisual3D.Content> </ModelVisual3D> <Viewport3D.Camera> <PerspectiveCamera Position = "1.5, 2, 3" LookDirection = "-1.5, -2, -3" UpDirection = "0, 1, 0" FieldOfView = "60"> <PerspectiveCamera.Transform> <Transform3DGroup> <RotateTransform3D> <RotateTransform3D.Rotation> <AxisAngleRotation3D Axis="0 1 0" Angle="{Binding ElementName=hscroll, Path=Value}" /> </RotateTransform3D.Rotation> </RotateTransform3D> <RotateTransform3D> <RotateTransform3D.Rotation> <AxisAngleRotation3D Axis="1 0 0" Angle="{Binding ElementName=vscroll, Path=Value}" /> </RotateTransform3D.Rotation> </RotateTransform3D> </Transform3DGroup> </PerspectiveCamera.Transform> </PerspectiveCamera> </Viewport3D.Camera> </Viewport3D>
If you made this, please take a bow. I applaud you.
PS: My project had System.Windows.Forms included, not sure if that's for this.
- Edited by George-Frias Friday, March 10, 2017 12:04 AM The small nice guy fix.
-
-
You cant rotate a picturebox.
However you can draw a rotated image in a panel or picturebox. There are lots of possibilities.
Here is a panel class with added rotation and scaling. It fits the rotated image to the panel size.
'example using PanelEx class for rotating and scaling images to fit in a panel Public Class Form4 'declare the panelEx and add to form Private WithEvents PictureEx1 As New PanelEx With { .Parent = Me, .BackColor = Color.SteelBlue, .bgBmp = New Bitmap("c:\bitmaps\rusty.jpg"), .Rotation = -45, .ScaleFactor = 0.9} 'set scalefactor to enlarge or reduce image in panel Private Sub Form4_Resize(sender As Object, e As EventArgs) Handles Me.Resize Dim border As Integer = 20 PictureEx1.Location = New Point(border, border) PictureEx1.Size = New Size(ClientSize.Width - (2 * border), ClientSize.Height - (2 * border)) End Sub Private Sub Form6_Load(sender As Object, e As EventArgs) Handles MyBase.Load Text = "Rotate Image Example" BackColor = Color.Black AutoSize = False Form4_Resize(0, Nothing) End Sub End Class 'rotates and fits image to panel Public Class PanelEx Inherits Panel Public bgBmp As Bitmap Public Rotation As Single = 0 Public ScaleFactor As Single = 1 Public Sub New() DoubleBuffered = True End Sub Private Sub PanelEx_Resize(sender As Object, e As EventArgs) Handles Me.Resize Invalidate() End Sub Private Sub PictureboxEx_Paint(sender As Object, e As PaintEventArgs) Handles Me.Paint Dim ScreenCenter As New Point(CInt(ClientSize.Width / 2), CInt(ClientSize.Height / 2)) Dim srcRect As New Rectangle(0, 0, bgBmp.Width, bgBmp.Height) Using pth As New Drawing2D.GraphicsPath, mx As New Drawing2D.Matrix 'fit the rotated image to the picturebox 'get the rotated size by using a path bounds mx.RotateAt(Rotation, ScreenCenter) pth.AddRectangle(srcRect) pth.Transform(mx) Dim boundsRect As RectangleF = pth.GetBounds() Dim scaleRatio As Double = 1 'compare rotated size to normal, 'fit to smallest picturebox dimension If ClientSize.Width / ClientSize.Height > boundsRect.Width / boundsRect.Height Then scaleRatio = ScaleFactor * ClientSize.Height / boundsRect.Height Else scaleRatio = ScaleFactor * ClientSize.Width / boundsRect.Width End If 'new image rectangle size Dim destWidth As Integer = CInt(srcRect.Width * scaleRatio) Dim destHeight As Integer = CInt(srcRect.Height * scaleRatio) Dim destRect As New Rectangle(CInt(ScreenCenter.X - destWidth / 2), CInt(ScreenCenter.Y - destHeight / 2), destWidth, destHeight) e.Graphics.Clear(BackColor) 'rotate the drawing surface about the center of picturebox and draw e.Graphics.Transform = mx e.Graphics.DrawImage(bgBmp, destRect, srcRect, GraphicsUnit.Pixel) e.Graphics.ResetTransform() e.Graphics.DrawString("tommytwotrain", New Font("arial", 10, FontStyle.Bold), Brushes.White, 4, Height - 20) End Using End Sub End Class
- Marked as answer by Tabzee Friday, March 10, 2017 3:27 PM
-
-
-
-