In your original post you didn't mention that you want to prevent clipping. So I decided to give you a link to article with simple and easy to understand approach. In that case (with your additional requirements) I will provide you a source which works fine for me. It may look a little bit complicated but I thoroughly commented the source. Here you go:
public static Bitmap RotateImage(Bitmap bmpSrc, float theta, Color bkColor)
{
Matrix mRotate = new Matrix();
mRotate.Translate(bmpSrc.Width / -2, bmpSrc.Height / -2, MatrixOrder.Append);
mRotate.RotateAt(theta, new Point(0, 0), MatrixOrder.Append);
using (GraphicsPath gp = new GraphicsPath())
{
gp.AddPolygon(new Point[] { new Point(0, 0), new Point(bmpSrc.Width, 0), new Point(0, bmpSrc.Height) });
gp.Transform(mRotate);
PointF[] pts = gp.PathPoints;
PixelFormat pfDest = default(PixelFormat);
pfDest = (bkColor == Color.Transparent) ? PixelFormat.Format32bppArgb : bmpSrc.PixelFormat;
Rectangle bbox = BoundingBox(bmpSrc, mRotate);
Bitmap bmpDest = new Bitmap(bbox.Width, bbox.Height, pfDest);
using (Graphics gDest = Graphics.FromImage(bmpDest))
{
Matrix mDest = new Matrix();
mDest.Translate(bmpDest.Width / 2, bmpDest.Height / 2, MatrixOrder.Append);
gDest.Clear(bkColor);
gDest.Transform = mDest;
gDest.DrawImage(bmpSrc, pts);
return bmpDest;
}
}
}
private static Rectangle BoundingBox(Image img, Matrix matrix)
{
GraphicsUnit gu = new GraphicsUnit();
Rectangle rImg = Rectangle.Round(img.GetBounds(ref gu));
Point topLeft = new Point(rImg.Left, rImg.Top);
Point topRight = new Point(rImg.Right, rImg.Top);
Point bottomRight = new Point(rImg.Right, rImg.Bottom);
Point bottomLeft = new Point(rImg.Left, rImg.Bottom);
Point[] points = new Point[] { topLeft, topRight, bottomRight, bottomLeft };
GraphicsPath gp = new GraphicsPath
(
points,
new byte[] {
(byte)PathPointType.Start,
(byte)PathPointType.Line,
(byte)PathPointType.Line,
(byte)PathPointType.Line
}
);
gp.Transform(matrix);
return Rectangle.Round(gp.GetBounds());
}
You will need to add the following additional using statements in order to compile the code:
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
Now you can use the above code like this:
private void btnRotateGraphics_Click(object sender, EventArgs e)
{
pictureBox1.Image = RotateImage((Bitmap)pictureBox1.Image, 90.0f, Color.AliceBlue);
pictureBox1.Invalidate();
}
I hope this helps. :)