旋转图形?

我有这个代码,绘制图像。

private void timer1_Tick(object sender, EventArgs e) { Invalidate(); } protected override void OnPaint(PaintEventArgs e) { var tempRocket = new Bitmap(Properties.Resources.rocket); using (var g = Graphics.FromImage(tempRocket)) { e.Graphics.DrawImage(tempRocket, 150, 150); } } 

然而我该如何旋转呢?

 public static Bitmap RotateImage(Bitmap b, float angle) { //create a new empty bitmap to hold rotated image Bitmap returnBitmap = new Bitmap(b.Width, b.Height); //make a graphics object from the empty bitmap using(Graphics g = Graphics.FromImage(returnBitmap)) { //move rotation point to center of image g.TranslateTransform((float)b.Width / 2, (float)b.Height / 2); //rotate g.RotateTransform(angle); //move image back g.TranslateTransform(-(float)b.Width / 2, -(float)b.Height / 2); //draw passed in image onto graphics object g.DrawImage(b, new Point(0, 0)); } return returnBitmap; } 

有一些Graphics.DrawImage重载,它采用三个点的数组来定义目标的平行四边形,例如:

Graphics.DrawImage方法(Image,Point [])

备注

destPoints参数指定平行四边形的三个点。 三点结构表示平行四边形的左上角,右上角和左下角。 第四点从前三个推断出来形成平行四边形。

由图像参数表示的图像被缩放并剪切以适合由destPoints参数指定的平行四边形的形状。

MSDN上还有一篇文章描述了这种方法的用法: 如何:旋转,reflection和歪斜图像 ,使用下面的代码示例。 不幸的是,该示例通过使图像偏斜来使问题复杂化。

 Point[] destinationPoints = { new Point(200, 20), // destination for upper-left point of original new Point(110, 100), // destination for upper-right point of original new Point(250, 30)}; // destination for lower-left point of original Image image = new Bitmap("Stripes.bmp"); // Draw the image unaltered with its upper-left corner at (0, 0). e.Graphics.DrawImage(image, 0, 0); // Draw the image mapped to the parallelogram. e.Graphics.DrawImage(image, destinationPoints); 

与使用Graphics.Transform属性相比,主要区别是:

  • 此方法不允许您以度为单位指定旋转角度 – 您必须使用一些简单的三角函数来导出点。
  • 此转换仅适用于特定图像。
    • 很好,如果你只需要绘制一个旋转的图像,其他一切都是非旋转的,因为你不必重置Graphics.Transform
    • 如果您想要将多个东西一起旋转(即旋转“相机”),则会很糟糕。

使用Graphics.RotateTransform旋转图像。

 protected override void OnPaint(PaintEventArgs e) { var tempRocket = new Bitmap(Properties.Resources.rocket); e.Graphics.RotateTransform(30.0F); e.Graphics.DrawImage(tempRocket, 150, 150); } 

没有裁剪的版本:

 private Bitmap RotateBitmap(Bitmap bitmap, float angle) { int w, h, x, y; var dW = (double)bitmap.Width; var dH = (double)bitmap.Height; double degrees = Math.Abs(angle); if (degrees <= 90) { double radians = 0.0174532925 * degrees; double dSin = Math.Sin(radians); double dCos = Math.Cos(radians); w = (int)(dH * dSin + dW * dCos); h = (int)(dW * dSin + dH * dCos); x = (w - bitmap.Width) / 2; y = (h - bitmap.Height) / 2; } else { degrees -= 90; double radians = 0.0174532925 * degrees; double dSin = Math.Sin(radians); double dCos = Math.Cos(radians); w = (int)(dW * dSin + dH * dCos); h = (int)(dH * dSin + dW * dCos); x = (w - bitmap.Width) / 2; y = (h - bitmap.Height) / 2; } var rotateAtX = bitmap.Width / 2f; var rotateAtY = bitmap.Height / 2f; var bmpRet = new Bitmap(w, h); bmpRet.SetResolution(bitmap.HorizontalResolution, bitmap.VerticalResolution); using (var graphics = Graphics.FromImage(bmpRet)) { graphics.Clear(Color.White); graphics.TranslateTransform(rotateAtX + x, rotateAtY + y); graphics.RotateTransform(angle); graphics.TranslateTransform(-rotateAtX - x, -rotateAtY - y); graphics.DrawImage(bitmap, new PointF(0 + x, 0 + y)); } return bmpRet; } 

主要资源

您需要应用转换矩阵。 在这里你可以找到关于GDI +转换的好例子