Click here to Skip to main content
15,881,833 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi,

To rotate image in picturebox i tried below code.

C#
public static Bitmap RotateImg(Bitmap bmp, float angle, Color bkColor)
        {
            int w = bmp.Width;
            int h = bmp.Height;
            PixelFormat pf = default(PixelFormat);
            if (bkColor == Color.Transparent)
            {
                pf = PixelFormat.Format32bppArgb;
            }
            else
            {
                pf = bmp.PixelFormat;
            }
            Bitmap tempImg = new Bitmap(w, h, pf);
            Graphics g = Graphics.FromImage(tempImg);
            g.Clear(bkColor);
            g.DrawImageUnscaled(bmp, 1, 1);
            g.Dispose();
            GraphicsPath path = new GraphicsPath();
            path.AddRectangle(new RectangleF(0f, 0f, w, h));
            Matrix mtrx = new Matrix();
            //Using System.Drawing.Drawing2D.Matrix class 
            mtrx.Rotate(angle);
            RectangleF rct = path.GetBounds(mtrx);
            Bitmap newImg = new Bitmap(Convert.ToInt32(rct.Width), Convert.ToInt32(rct.Height), pf);
            g = Graphics.FromImage(newImg);
            g.Clear(bkColor);
            g.TranslateTransform(-rct.X, -rct.Y);
            g.RotateTransform(angle);
            g.InterpolationMode = InterpolationMode.HighQualityBilinear;
            g.DrawImageUnscaled(tempImg, 0, 0);
            g.Dispose();
            tempImg.Dispose();
            return newImg;
        }

This code is referred from the link http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/a1e62e03-d732-444d-bb3d-6e7907fd5e16[^]

But it is not working. I have tried using RotateFlip method. I want similar type of behaviour using directly graphics object functions.
Please let me know what is not correct in above code.

Thanks on advance.
Posted
Updated 22-Jul-10 3:13am
v2

If you want to rotate your image only on 90/180/270-degrees use the Image.RotateFlip[^] method because it is faster than using Graphics.
If you want to rotate your image on arbitrary angle, have a look at this[^] CodeProject article. It is not the fastest way to rotate an image, but it is simpler and easier to understand for you. :)
 
Share this answer
 
Comments
ISharda 23-Jul-10 0:34am    
I accept its easy to use the API and it would be faster. But I dont know what is this API internally doing.
e.g. Using Graphics I can set the InterpolationMode, I can ensure that the PixelFormat remain same as original.
Using RotateFlip API how do i ensure that the image quality remain same.

Also I tried the link suggested by you. When I rotate it 90 degree, the image is clipped. How to solve it.
Nuri Ismail 23-Jul-10 3:56am    
I've posted an additional answer, because it contains code snippets and I cannot paste all of this in a comment. Please see my next answer which is conformable to the comment posted by you. :)
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:
C#
// Rotates the input image by theta degrees around center
// and fills the background with specified color.
public static Bitmap RotateImage(Bitmap bmpSrc, float theta, Color bkColor)
{
    // Create a matrix for the geometric transformations.
    // Check out the documentation of this class
    Matrix mRotate = new Matrix();

    // Apply the transformations on the matrix:
    // 1) We will rotate around the center, so apply translation to the center of the image
    mRotate.Translate(bmpSrc.Width / -2, bmpSrc.Height / -2, MatrixOrder.Append);
    // 2) Apply the rotation after the translation
    mRotate.RotateAt(theta, new Point(0, 0), MatrixOrder.Append);

    using (GraphicsPath gp = new GraphicsPath())
    {
        // Transform image points by rotation matrix
        gp.AddPolygon(new Point[] { new Point(0, 0), new Point(bmpSrc.Width, 0), new Point(0, bmpSrc.Height) });
        gp.Transform(mRotate);

        // Get the points after transformation
        PointF[] pts = gp.PathPoints;

        // Ensure the selection of correct pixel format for the destination bitmap
        PixelFormat pfDest = default(PixelFormat);
        pfDest = (bkColor == Color.Transparent) ? PixelFormat.Format32bppArgb : bmpSrc.PixelFormat;

        // Create destination bitmap sized to contain rotated source image
        Rectangle bbox = BoundingBox(bmpSrc, mRotate);
        Bitmap bmpDest = new Bitmap(bbox.Width, bbox.Height, pfDest);

        // Create new graphics from the destination bitmap
        using (Graphics gDest = Graphics.FromImage(bmpDest))
        {
            // NOTE: The interpolation mode for gDest could be set for better quality.
            // For example:
            // gDest.InterpolationMode = InterpolationMode.HighQualityBicubic;

            // Draw the source into destination:
            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;
        }
    }
}

// Returns the bounding box of the image after applying the
// transformations from the input matrix
private static Rectangle BoundingBox(Image img, Matrix matrix)
{
    // Get the bounding box of the input image
    GraphicsUnit gu = new GraphicsUnit();
    Rectangle rImg = Rectangle.Round(img.GetBounds(ref gu));

    // Create an array of points from the bounding box
    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 };

    // Create a graphics path from the points.
    // We will apply transformations on graphics path, not on the input image
    GraphicsPath gp = new GraphicsPath
                                    (
                                    points,
                                    new byte[] {
                                                 (byte)PathPointType.Start,
                                                 (byte)PathPointType.Line,
                                                 (byte)PathPointType.Line,
                                                 (byte)PathPointType.Line
                                               }
                                    );

    // Apply the transformations from the input matrix to the graphics path
    gp.Transform(matrix);

    // Return the bounds of the graphics path after transformation
    return Rectangle.Round(gp.GetBounds());
}


You will need to add the following additional using statements in order to compile the code:
C#
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;


Now you can use the above code like this:
C#
private void btnRotateGraphics_Click(object sender, EventArgs e)
{
    pictureBox1.Image = RotateImage((Bitmap)pictureBox1.Image, 90.0f, Color.AliceBlue);
    pictureBox1.Invalidate();
}


I hope this helps. :)
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900