旋转图形?

时间:2011-03-02 20:17:33

标签: c#

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

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);
    }
}

然而,如何旋转呢?

5 个答案:

答案 0 :(得分:27)

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;
}

答案 1 :(得分:7)

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

  

Graphics.DrawImage Method (Image, Point[])

     

说明

     

destPoints参数指定   平行四边形的三个点。该   三点结构代表了   左上,右上,和   左下角   平行四边形。第四点是   从前三个推断到   形成平行四边形。

     

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

MSDN上还有一篇文章描述了这种方法的使用:How to: Rotate, Reflect, and Skew Images,以下代码示例。不幸的是,该示例还使图像偏斜,从而使问题复杂化。

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
    • 如果您想要将多个东西一起旋转(即旋转“相机”),则会很糟糕。

答案 2 :(得分:2)

使用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);
}

答案 3 :(得分:2)

没有裁剪的版本:

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;
    }

Primary source

答案 4 :(得分:0)

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