Click here to Skip to main content
6,305,776 members and growing! (17,118 online)
Email Password   helpLost your password?
Languages » C / C++ Language » General     Intermediate

Rotating PictureBox Control

By Chris Kolkman

A PictureBox control that lets you rotate images.
VB.NET 1.1, Win2K, WinXP, GDI+, VS.NET2003, Dev
Posted:26 Apr 2005
Updated:29 Jul 2005
Views:70,068
Bookmarked:16 times
Announcements
Loading...
 
Search    
Advanced Search
printPrint   Broken Article?Report       add Share
  Discuss Discuss   Recommend Article Email
9 votes for this article.
Popularity: 3.18 Rating: 3.33 out of 5
3 votes, 33.3%
1
1 vote, 11.1%
2

3
2 votes, 22.2%
4
3 votes, 33.3%
5

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

About the Author

Chris Kolkman


Member

Occupation: Software Developer
Location: United States United States

Other popular C / C++ Language articles:

Article Top
You must Sign In to use this message board.
FAQ FAQ 
 
Noise Tolerance  Layout  Per page   
 Msgs 1 to 25 of 27 (Total in Forum: 27) (Refresh)FirstPrevNext
GeneralRotating Picturebox Control Pinmemberactpfd6:42 25 Jun '07  
GeneralRe: Rotating Picturebox Control PinmemberChris Kolkman7:39 25 Jun '07  
GeneralRe: Rotating Picturebox Control Pinmemberactpfd23:28 25 Jun '07  
GeneralRe: Rotating Picturebox Control PinmemberChris Kolkman4:10 26 Jun '07  
GeneralRe: Rotating Picturebox Control Pinmemberactpfd4:33 26 Jun '07  
GeneralRe: Rotating Picturebox Control PinmemberChris Kolkman4:46 26 Jun '07  
GeneralRe: Rotating Picturebox Control Pinmemberactpfd4:59 26 Jun '07  
GeneralRe: Rotating Picturebox Control PinmemberChris Kolkman5:22 26 Jun '07  
GeneralRe: Rotating Picturebox Control Pinmemberactpfd5:53 26 Jun '07  
GeneralRe: Rotating Picturebox Control PinmemberChris Kolkman5:53 26 Jun '07  
GeneralRe: Idid not succed to load the demo it seems to the same files as the sources PinmemberChris Kolkman10:53 19 Mar '07  
Questiondrawing a rombus within the rotated rectangle PinmemberJK Rajesh2:51 29 Jan '07  
GeneralHow do I calculate the angle.value of a point? Pinmemberfurjaw18:27 23 Jun '06  
GeneralRe: How do I calculate the angle.value of a point? PinmemberChris Kolkman5:12 24 Jun '06  
GeneralI do not see the trigonometry code Pinmemberfurjaw7:34 23 Jun '06  
GeneralRe: I do not see the trigonometry code PinmemberChris Kolkman9:45 23 Jun '06  
GeneralTimer Tick Subroutine Not Needed Pinmemberfurjaw7:32 23 Jun '06  
GeneralRe: Timer Tick Subroutine Not Needed PinmemberChris Kolkman9:55 23 Jun '06  
GeneralWhy not use System.Drawing.Drawing2D.Matrix PinmemberRoss Presser10:56 1 Nov '05  
GeneralRe: Why not use System.Drawing.Drawing2D.Matrix PinmemberChris Kolkman11:25 1 Nov '05  
GeneralThis is a code website Pinmemberpascal ganaye7:28 22 Jul '05  
GeneralRe: This is a code website PinmemberChris Kolkman5:00 26 Jul '05  
GeneralRe: This is a code website [modified] Pinmemberfurjaw19:55 22 Jun '06  
GeneralRe: This is a code website PinmemberChris Kolkman2:22 23 Jun '06  
GeneralRe: This is a code website Pinmemberfurjaw20:27 27 Jun '06  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 29 Jul 2005
Editor: Smitha Vijayan
Copyright 2005 by Chris Kolkman
Everything else Copyright © CodeProject, 1999-2009
Web12 | Advertise on the Code Project