J. Doe
J. Doe

Reputation: 29

Graphics.RotateTransform not working

I'm not sure why it's not working...

    Bitmap img = (Bitmap)Properties.Resources.myBitmap.Clone();
    Graphics g = Graphics.FromImage(img);
    g.RotateTransform(45);
    pictureBox1.Image = img;

The image is displayed, but it is not rotated.

Upvotes: 1

Views: 2263

Answers (2)

Peter Duniho
Peter Duniho

Reputation: 70661

One uses a Graphics instance to draw. Changes to the Graphics instance affect the object used to create the Graphics instance only when drawing to that object. This includes the transformation. Simply creating a Graphics instance from a bitmap object and changing its transform won't have any effect (as you've found).

The following method will create a new Bitmap object, a rotated version of the original passed to it:

private Image RotateImage(Bitmap bitmap)
{
    PointF centerOld = new PointF((float)bitmap.Width / 2, (float)bitmap.Height / 2);
    Bitmap newBitmap = new Bitmap(bitmap.Width, bitmap.Height, bitmap.PixelFormat);

    // Make sure the two coordinate systems are the same
    newBitmap.SetResolution(bitmap.HorizontalResolution, bitmap.VerticalResolution);

    using (Graphics g = Graphics.FromImage(newBitmap))
    {
        Matrix matrix = new Matrix();

        // Rotate about old image center point
        matrix.RotateAt(45, centerOld);

        g.Transform = matrix;
        g.DrawImage(bitmap, new Point());
    }

    return newBitmap;
}

You could use it like this:

pictureBox1.Image = RotateImage(Properties.Resources.myBitmap);

You will note, however, that because the new bitmap has the same dimensions as the old bitmap, rotating the image within the new bitmap causes cropping at the edges.

You can fix this (if needed…it's not clear from your question whether it is) by calculating the new boundary of the bitmap based on the rotation; pass the corner points of your bitmap to the Matrix.TransformPoints() method, then find the min and max of the X and Y coordinates to create a new bounding rectangle, and finally use the width and height to create a new bitmap into which you can rotate the old one without cropping.

Finally, note that this is all very complicated mainly because you're using Winforms. WPF has much better support for rotating visual elements, and it all can be done simply by manipulating the WPF Image control used to display the bitmap.

Upvotes: 2

Joel
Joel

Reputation: 516

You are rotating the graphics interface, but not using it to draw the image. The picturebox control is quite simple, and may not be your friend here.

Try using g.DrawImage(...) see here to display the image instead

Upvotes: 1

Related Questions