Click here to Skip to main content
Click here to Skip to main content

Rotating PictureBox Control

, 29 Jul 2005
Rate this:
Please Sign up or sign in to vote.
A PictureBox control that lets you rotate images.

Sample Image - rimage.jpg

Introduction

How many times have you wanted to rotate an image in a PictureBox control? I know I've wanted to do it on many occasions.

This control makes it simple to rotate your images. Referencing it is easy in code - the namespace is System.Windows.Forms so you can easily declare one as RImage.

Properties/Methods

This control inherits everything so any property/method a PictureBox has, this control will have as well - however, there are several properties that will allow you other options that were built into the control.

  • Public Property ShowThrough() As Boolean
  • Public Property Direction() As DirectionEnum
  • Public Property Rotation() As Integer
  • Public Property TransparentColor() As Color

ShowThrough will determine whether or not space not used by the image will be transparent and show the control below it. This is accomplished using regions.

Direction as you notice is declared as DirectionEnum. This enumeration was created for the control. It tells the control which way to rotate the image: Clockwise, or Counter_Clockwise.

Rotation is the angle of rotation of the image. It is in degrees. The range is 0 to 359; however, inputting a number outside of the range will scale it to the appropriate angle that is in the range.

TransparentColor will allow you to set a transparent color for the image. The demo project has an image included with a Lime background. If the TransparentColor property is set to Lime - that color in the image will be painted transparent. Unfortunately, it doesn't show the controls below it through, just the parent's background color.

Adding the Control

Right-click on an empty area of your toolbox and choose Add/Remove Items. At the dialog screen on the .NET Framework Components tab, choose Browse and navigate to the DLL file. Once you've done this, hit OK.

You've now added the control to the toolbox.

Using the Control

Using the control is simple. It works almost exactly like the PictureBox control. Add one to your form, and give it an image. Once it has an image, ShowThrough will start working (if there is no image, OnPaint quits before it can set the transparent region) if it is set.

Now just set your Direction from the drop-down box in the Properties window and enter an angle for your Rotation.

If you'd like to set a transparent color for your image - you can do that with TransparentColor in the Properties window.

How it works

All of the rotation is handled in the OnPaint event. I start by getting the current corners of the image.

Dim bm_in As New Bitmap(MyBase.Image)

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)}

Next I grab the center of the image - the point we want to rotate around - and subtract from each of the corners.

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

Now we need to get the Sine of theta, and the Cosine of theta - which means we need theta.

Dim theta As Single = CSng((_degree) * _direction) * PI / 180
Dim sin_theta As Single = Sin(theta)
Dim cos_theta As Single = Cos(theta)

Here is where the magic comes in, we need to apply the rotation formulas to all the corners.

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 = (Y * cos_theta) + (X * sin_theta)
Next

OK, we've got the rotated corners, let's fix the offset we created when finding the rotation point, and for that we'll need the minimum x and y values.

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

For i = 0 To 3
    corners(i).X -= xmin
    corners(i).Y -= ymin
Next

Now we can actually output the rotated image, but first I create a region using a function to create it based on these corners.

Dim bm_out As New Bitmap(CInt(-2 * xmin), CInt(-2 * ymin))
Dim bgr As Graphics = Graphics.FromImage(bm_out)
Dim rg As Region = CreateTransRegion(corners)
Dim tp As Point = corners(3)
ReDim Preserve corners(2)
bgr.DrawImage(bm_in, corners)

Now we have the rotated image in an output buffer, plus a region to allow transparency for the parts of the control that won't draw the image. Now comes the implementation of the SizeMode. For StretchImage, we'll need the width and height of the rotated image - this is easy as it's stored in the corners array at index 3 - and for stretching or centering we'll need a new region.

Dim gr_out As Graphics = pe.Graphics
gr_out.FillRectangle(New SolidBrush(Me.BackColor), 0, 0, Me.Width, Me.Height)
bm_in.MakeTransparent(_transColor)
If _sizemode = PictureBoxSizeMode.StretchImage Then
    Dim maxW As Integer = tp.X
    Dim maxH As Integer = tp.Y
    For t As Integer = 0 To 2
        If maxW < corners(t).X Then maxW = corners(t).X
        If maxH < corners(t).Y Then maxH = corners(t).Y
    Next
    'get hscale
    Dim hscale As Double = Me.Width / maxW
    'get vscale
    Dim vscale As Double = Me.Height / maxH
    'convert points
    corners(0) = New Point(corners(0).X * hscale, corners(0).Y * vscale)
    corners(1) = New Point(corners(1).X * hscale, corners(1).Y * vscale)
    corners(2) = New Point(corners(2).X * hscale, corners(2).Y * vscale)
    gr_out.DrawImage(bm_out, 0, 0, Me.Width, Me.Height)
    Dim np(3) As Point
    np(0) = corners(0)
    np(1) = corners(1)
    np(2) = corners(2)
    np(3) = New Point(tp.X * hscale, tp.Y * vscale)
    rg = CreateTransRegion(np)

We don't need quite so much for centering the image.

ElseIf _sizemode = PictureBoxSizeMode.CenterImage Then
    Dim wadd As Integer = CInt((Me.Width / 2) - (bm_out.Width / 2))
    Dim hadd As Integer = CInt((Me.Height / 2) - (bm_out.Height / 2))
    corners(0) = New Point(corners(0).X + wadd, corners(0).Y + hadd)
    corners(1) = New Point(corners(1).X + wadd, corners(1).Y + hadd)
    corners(2) = New Point(corners(2).X + wadd, corners(2).Y + hadd)
    gr_out.DrawImage(bm_in, corners)
    Dim np(3) As Point
    np(0) = corners(0)
    np(1) = corners(1)
    np(2) = corners(2)
    np(3) = New Point(tp.X + wadd, tp.Y + hadd)
    rg = CreateTransRegion(np)

Any other size modes just get output to 0,0, so we don't need anything special there, except for AutoSize - which just changes the control's size to match the image.

Else
    gr_out.DrawImage(bm_in, corners)
End If
If _sizemode = PictureBoxSizeMode.AutoSize Then
    MyBase.Width = bm_out.Width
    MyBase.Height = bm_out.Height
End If

The last thing we take care of is the region (for transparency), but if the property ShowThrough is changed to False then we need to make sure to get rid of any existing region.

Me.Region = Nothing
If _showThrough Then
    Me.Region = rg
End If

And that's it! It is certainly possible to modify it to rotate around a point other than the center (although I haven't tried).

Suggestions/Bugs

If you want to send me any bugs/suggestions, please send them to codeproject@stdominion.net.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

Chris Kolkman
Software Developer
United States United States
No Biography provided

Comments and Discussions

 
GeneralMy vote of 4 PinmemberMember 819853825-Sep-11 16:25 
GeneralWorks great. [modified] Pinmemberemre20084-Nov-09 19:36 
GeneralRotating Picturebox Control Pinmemberactpfd25-Jun-07 5:42 
GeneralRe: Rotating Picturebox Control PinmemberChris Kolkman25-Jun-07 6:39 
GeneralRe: Rotating Picturebox Control Pinmemberactpfd25-Jun-07 22:28 
GeneralRe: Rotating Picturebox Control PinmemberChris Kolkman26-Jun-07 3:10 
GeneralRe: Rotating Picturebox Control Pinmemberactpfd26-Jun-07 3:33 
GeneralRe: Rotating Picturebox Control PinmemberChris Kolkman26-Jun-07 3:46 
GeneralRe: Rotating Picturebox Control Pinmemberactpfd26-Jun-07 3:59 
GeneralRe: Rotating Picturebox Control PinmemberChris Kolkman26-Jun-07 4:22 
GeneralRe: Rotating Picturebox Control Pinmemberactpfd26-Jun-07 4:53 
GeneralRe: Rotating Picturebox Control PinmemberChris Kolkman26-Jun-07 4:53 
GeneralRe: Idid not succed to load the demo it seems to the same files as the sources PinmemberChris Kolkman19-Mar-07 9:53 
Questiondrawing a rombus within the rotated rectangle PinmemberJK Rajesh29-Jan-07 1:51 
QuestionHow do I calculate the angle.value of a point? Pinmemberfurjaw23-Jun-06 17:27 
AnswerRe: How do I calculate the angle.value of a point? PinmemberChris Kolkman24-Jun-06 4:12 
GeneralI do not see the trigonometry code Pinmemberfurjaw23-Jun-06 6:34 
GeneralRe: I do not see the trigonometry code PinmemberChris Kolkman23-Jun-06 8:45 
GeneralTimer Tick Subroutine Not Needed Pinmemberfurjaw23-Jun-06 6:32 
GeneralRe: Timer Tick Subroutine Not Needed PinmemberChris Kolkman23-Jun-06 8:55 
GeneralWhy not use System.Drawing.Drawing2D.Matrix PinmemberRoss Presser1-Nov-05 9:56 
GeneralRe: Why not use System.Drawing.Drawing2D.Matrix PinmemberChris Kolkman1-Nov-05 10:25 
GeneralThis is a code website Pinmemberpascal ganaye22-Jul-05 6:28 
GeneralRe: This is a code website PinmemberChris Kolkman26-Jul-05 4:00 
GeneralRe: This is a code website [modified] Pinmemberfurjaw22-Jun-06 18:55 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web02 | 2.8.140827.1 | Last Updated 29 Jul 2005
Article Copyright 2005 by Chris Kolkman
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid