There are some looooong and hungry algorithms for doing so, but as of yet I haven't come up with or found anything particularly fast.

- 64,767
- 30
- 146
- 239

- 2,463
- 8
- 30
- 46
-
Hello! Any followup? What you end-up using after all? Have you measured the time of the flipping? Have you compared it with EmguCV? I'm looking for the fastest way to rotate 90 and 180 degrees a image in C#. – Pedro77 May 23 '13 at 20:41
-
For simple 90 and 180 degree rotations, definitely use GDI+. It has 90 degree rotations build in. For arbitrary angles, use LockBits. – Bloodyaugust May 28 '13 at 22:26
5 Answers
The fastest way is to this is to use unsafe calls to manipulate the image memory directly using LockBits
. It sounds scary but it's pretty straight forward. If you search for LockBits you'll find plently of examples such as here.
The interesting bit is:
BitmapData originalData = originalBitmap.LockBits(
new Rectangle(0, 0, originalWidth, originalHeight),
ImageLockMode.ReadOnly,
PixelFormat.Format32bppRgb);
Once you have the BitmapData you can pass the pixels and map them into a new image (again using LockBits). This is significantly quicker than using the Graphics
API.

- 19,064
- 3
- 47
- 70
-
BTW the correct (and slower) way to do this using the Graphics API without clipping is http://stackoverflow.com/questions/2352804/how-do-i-prevent-clipping-when-rotating-an-image-in-c. – TheCodeKing Sep 27 '10 at 20:55
-
The first (unaccepted) answer is what I assume you're referring to? – Bloodyaugust Sep 27 '10 at 22:57
-
I awarded the bounty to you, because you led me to my eventual answer, although it wasn't LockBits. Turns out I had to use safe code only... meh. – Bloodyaugust Sep 28 '10 at 05:13
-
@Bloodyaugust I just meant how to impelement rotation without clipping using the graphics API. I wasn't referring to the previous answer directly :) – TheCodeKing Sep 28 '10 at 06:05
Here's what I ended up doing (after an extensive amount of continued research, and the helpful link provided by TheCodeKing):
public Image RotateImage(Image img, float rotationAngle)
{
// When drawing the returned image to a form, modify your points by
// (-(img.Width / 2) - 1, -(img.Height / 2) - 1) to draw for actual co-ordinates.
//create an empty Bitmap image
Bitmap bmp = new Bitmap((img.Width * 2), (img.Height *2));
//turn the Bitmap into a Graphics object
Graphics gfx = Graphics.FromImage(bmp);
//set the point system origin to the center of our image
gfx.TranslateTransform((float)bmp.Width / 2, (float)bmp.Height / 2);
//now rotate the image
gfx.RotateTransform(rotationAngle);
//move the point system origin back to 0,0
gfx.TranslateTransform(-(float)bmp.Width / 2, -(float)bmp.Height / 2);
//set the InterpolationMode to HighQualityBicubic so to ensure a high
//quality image once it is transformed to the specified size
gfx.InterpolationMode = InterpolationMode.HighQualityBicubic;
//draw our new image onto the graphics object with its center on the center of rotation
gfx.DrawImage(img, new PointF((img.Width / 2), (img.Height / 2)));
//dispose of our Graphics object
gfx.Dispose();
//return the image
return bmp;
}
Cheers!

- 2,463
- 8
- 30
- 46
-
You are rotating a bitmap twice the original size. This can be optimized. The bitmap size needed to support rotating without clipping is dependent on the rotation angle. – Jan Apr 14 '18 at 07:22
This answer returns both the offset it should be drawn on and the image which has been rotated.It works by recreating the new image to the size it should be without clipping the angles. Originally written by Hisenburg from the #C# IRC chatroom and Bloodyaugust.
public static double NormalizeAngle(double angle)
{
double division = angle / (Math.PI / 2);
double fraction = Math.Ceiling(division) - division;
return (fraction * Math.PI / 2);
}
public static Tuple<Image,Size> RotateImage(Image img, double rotationAngle)
{
double normalizedRotationAngle = NormalizeAngle(rotationAngle);
double widthD = img.Width, heightD = img.Height;
double newWidthD, newHeightD;
newWidthD = Math.Cos(normalizedRotationAngle) * widthD + Math.Sin(normalizedRotationAngle) * heightD;
newHeightD = Math.Cos(normalizedRotationAngle) * heightD + Math.Sin(normalizedRotationAngle) * widthD;
int newWidth, newHeight;
newWidth = (int)Math.Ceiling(newWidthD);
newHeight = (int)Math.Ceiling(newHeightD);
Size offset = new Size((newWidth - img.Width) / 2,(newHeight - img.Height) / 2);
Bitmap bmp = new Bitmap(newWidth, newHeight);
Graphics gfx = Graphics.FromImage(bmp);
//gfx.Clear(Color.Blue);
gfx.TranslateTransform((float)bmp.Width / 2, (float)bmp.Height / 2);
gfx.RotateTransform((float)(rotationAngle / Math.PI * 180));
gfx.TranslateTransform(-(float)bmp.Width / 2, -(float)bmp.Height / 2);
gfx.InterpolationMode = InterpolationMode.HighQualityBicubic;
gfx.DrawImage(img, new PointF((bmp.Width / 2 - img.Width / 2), (bmp.Height / 2 - img.Height / 2)));
gfx.Dispose();
return new Tuple<Image,Size>(bmp,offset);
}

- 386
- 3
- 10
-
John Thompson, @Bloodyaugust - I'm very curious as to what made you use the normalized angle approach over lets say using just a degrees to radians conversion here? – DotNetDude Aug 13 '19 at 12:29
-
void Graphics.RotateTransform(float angle);
This should rotate the image in C#. What is it doing instead?
I haven't experimented too much with GDI+. Remember to reverse the rotation after the image is drawn.

- 4,057
- 2
- 21
- 37
-
1
-
See: http://www.switchonthecode.com/tutorials/csharp-tutorial-image-editing-rotate – Michael Sep 21 '10 at 05:22
-
One of the comments solves the clipping problem, but doesn't (accurately) rotate around a center point. See the comment made by anonymous at 03/23/2009 - 22:23. – Bloodyaugust Sep 21 '10 at 05:30
-
@Michael: You may want to put that as an answer, not as a comment on my incorrect answer. ^^() – Sion Sheevok Sep 21 '10 at 06:20
-
-
@Jan - http://web.archive.org/web/20120209181532/http://www.switchonthecode.com/tutorials/csharp-tutorial-image-editing-rotate – Michael Feb 27 '19 at 22:44
System.Drawing.Image imageToRotate = System.Drawing.Image.FromFile(imagePath);
switch (rotationAngle.Value)
{
case "90":
imageToRotate.RotateFlip(RotateFlipType.Rotate90FlipNone);
break;
case "180":
imageToRotate.RotateFlip(RotateFlipType.Rotate180FlipNone);
break;
case "270":
imageToRotate.RotateFlip(RotateFlipType.Rotate270FlipNone);
break;
default:
throw new Exception("Rotation angle not supported.");
}
imageToRotate.Save(imagePath, ImageFormat.Jpeg);

- 1,762
- 15
- 25