Kevin
Kevin

Reputation: 3623

C# rotate bitmap 90 degrees

I'm trying to rotate a bitmap 90 degrees using the following function. The problem with it is that it cuts off part of the image when the height and width are not equal.

Notice the returnBitmap width = original.height and it's height = original.width

Can anyone help me solve this issue or point out what I'm doing wrong?

    private Bitmap rotateImage90(Bitmap b)
    {
        Bitmap returnBitmap = new Bitmap(b.Height, b.Width);
        Graphics g = Graphics.FromImage(returnBitmap);
        g.TranslateTransform((float)b.Width / 2, (float)b.Height / 2);
        g.RotateTransform(90);
        g.TranslateTransform(-(float)b.Width / 2, -(float)b.Height / 2);
        g.DrawImage(b, new Point(0, 0));
        return returnBitmap;
    }

Upvotes: 60

Views: 72730

Answers (3)

Rubens Farias
Rubens Farias

Reputation: 57936

What about this:

private void RotateAndSaveImage(String input, String output)
{
    //create an object that we can use to examine an image file
    using (Image img = Image.FromFile(input))
    {
        //rotate the picture by 90 degrees and re-save the picture as a Jpeg
        img.RotateFlip(RotateFlipType.Rotate90FlipNone);
        img.Save(output, System.Drawing.Imaging.ImageFormat.Jpeg);
    }
}

Upvotes: 116

thecaptain0220
thecaptain0220

Reputation: 2168

I came across and with a little modification I got it to work. I found some other examples and noticed something missing that made the difference for me. I had to call SetResolution, if I didn't the image ended up the wrong size. I also noticed the Height and Width were backwards, although I think there would be some modification for a non square image anyway. I figured I would post this for anyone who comes across this like I did with the same problem.

Here is my code

private static void RotateAndSaveImage(string input, string output, int angle)
{
    //Open the source image and create the bitmap for the rotatated image
    using (Bitmap sourceImage = new Bitmap(input))
    using (Bitmap rotateImage = new Bitmap(sourceImage.Width, sourceImage.Height))
    {
        //Set the resolution for the rotation image
        rotateImage.SetResolution(sourceImage.HorizontalResolution, sourceImage.VerticalResolution);
        //Create a graphics object
        using (Graphics gdi = Graphics.FromImage(rotateImage))
        {
            //Rotate the image
            gdi.TranslateTransform((float)sourceImage.Width / 2, (float)sourceImage.Height / 2);
            gdi.RotateTransform(angle);
            gdi.TranslateTransform(-(float)sourceImage.Width / 2, -(float)sourceImage.Height / 2);
            gdi.DrawImage(sourceImage, new System.Drawing.Point(0, 0));
        }

        //Save to a file
        rotateImage.Save(output);
    }
}

Upvotes: 3

finnw
finnw

Reputation: 48619

The bug is in your first call to TranslateTransform:

g.TranslateTransform((float)b.Width / 2, (float)b.Height / 2);

This transform needs to be in the coordinate space of returnBitmap rather than b, so this should be:

g.TranslateTransform((float)b.Height / 2, (float)b.Width / 2);

or equivalently

g.TranslateTransform((float)returnBitmap.Width / 2, (float)returnBitmap.Height / 2);

Your second TranslateTransform is correct, because it will be applied before the rotation.

However you're probably better off with the simpler RotateFlip method, as Rubens Farias suggested.

Upvotes: 10

Related Questions