Title: Rotate images
This program uses the following RotateBitmap method to rotate an image.
// Return a bitmap rotated around its center.
private Bitmap RotateBitmap(Bitmap bm, float angle)
{
// Make a Matrix to represent rotation
// by this angle.
Matrix rotate_at_origin = new Matrix();
rotate_at_origin.Rotate(angle);
// Rotate the image's corners to see how big
// it will be after rotation.
PointF[] points =
{
new PointF(0, 0),
new PointF(bm.Width, 0),
new PointF(bm.Width, bm.Height),
new PointF(0, bm.Height),
};
rotate_at_origin.TransformPoints(points);
float xmin, xmax, ymin, ymax;
GetPointBounds(points, out xmin, out xmax,
out ymin, out ymax);
// Make a bitmap to hold the rotated result.
int wid = (int)Math.Round(xmax - xmin);
int hgt = (int)Math.Round(ymax - ymin);
Bitmap result = new Bitmap(wid, hgt);
// Create the real rotation transformation.
Matrix rotate_at_center = new Matrix();
rotate_at_center.RotateAt(angle,
new PointF(wid / 2f, hgt / 2f));
// Draw the image onto the new bitmap rotated.
using (Graphics gr = Graphics.FromImage(result))
{
// Use smooth image interpolation.
gr.InterpolationMode = InterpolationMode.High;
// Clear with the color in the image's upper left corner.
gr.Clear(bm.GetPixel(0, 0));
//// For debugging. (It's easier to see the background.)
//gr.Clear(Color.LightBlue);
// Set up the transformation to rotate.
gr.Transform = rotate_at_center;
// Draw the image centered on the bitmap.
int x = (wid - bm.Width) / 2;
int y = (hgt - bm.Height) / 2;
gr.DrawImage(bm, x, y);
}
// Return the result bitmap.
return result;
}
When you rotate a rectangle, the result may be wider and taller than the original image because the rotated corners may stick out on the sides. This method returns a new image that is big enough to display all of the contents of the original image.
To get the dimensions of the rotated image, the code starts by creating a Matrix that rotates through the specified angle. It creates an array of PointF structures holding the bitmap's corners and uses the Matrix to rotate the corners.
The method then calls the GetPointBounds method to get the bounds for the rotated corners. That method simply loops through the points and keeps track and the minimum and maximum X and Y values. That method is straightforward so it isn't shown here.
Next the code creates a result bitmap big enough to hold the rotated image. It then creates a Matrix to represent rotation through the desired angle around the center of the result bitmap.
The method then creates a Graphics object associated with the result bitmap and sets that object's InterpolationMode property to produce a smooth result. The code clears the result bitmap with whatever color is in the original image's upper left corner. (The commented out debugging code fills the result bitmap with light blue so it's easy to see where the original image is drawn.)
Next the code sets the Graphics object's Transform property so it rotates anything it draws. Finally the method draws the original bitmap at a position that makes it centered on the result bitmap. The transform automatically rotates the image.
The rest of the program just lets you open an image file and displays the rotated result.
Download the example to experiment with it and to see additional details.
|