【问题标题】:How do I rotate image then move to the top left 0,0 without cutting off the image如何旋转图像然后移动到左上角 0,0 而不会切断图像
【发布时间】:2011-03-05 07:08:59
【问题描述】:

如何旋转图像然后移动到左上角 0,0 而不切断图像。

请阅读代码中的 cmets。我卡在第 3 步 我认为使用三角学应该可以解决这个问题。

谢谢

private 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
    Graphics g = Graphics.FromImage(returnBitmap);
    //STEP 1 move rotation point to top left
    g.TranslateTransform((float)0, (float)0);
    //STEP 2 rotate
    g.RotateTransform(angle);
    //STEP 3 move image back to top left without cutting off the image
    //SOME trigonometry calculation here
    int newY = b.Height;
    g.TranslateTransform(-(float)0, -newY);
    //draw passed in image onto graphics object
    g.DrawImage(b, new Point(0, 0));
    return returnBitmap;
}

【问题讨论】:

  • TranslateTransform(0,0) 不会像您认为的那样做。你想要TranslateTransform(b.Width/2, b.Height/2)。这会将图像的中心放置在原点。然而,其余的超出了我的范围。
  • 我虽然将所有内容移动到 0,0 坐标会使做正弦、余弦、正切的事情变得容易得多。我的示例不需要移动到 0,0,因为图像已经在 0,0

标签: c# gdi+


【解决方案1】:

这是否涵盖了“三角学”?我已将其设为第 0 步,因为我认为您需要先执行此操作。这样您就可以计算生成的位图的大小,这会更大 - 请参阅代码中的我的 cmets。

    private Bitmap RotateImage(Bitmap b, float Angle) {
        // The original bitmap needs to be drawn onto a new bitmap which will probably be bigger 
        // because the corners of the original will move outside the original rectangle.
        // An easy way (OK slightly 'brute force') is to calculate the new bounding box is to calculate the positions of the 
        // corners after rotation and get the difference between the maximum and minimum x and y coordinates.
        float wOver2 = b.Width / 2.0f;
        float hOver2 = b.Height / 2.0f;
        float radians = -(float)(Angle / 180.0 * Math.PI);
        // Get the coordinates of the corners, taking the origin to be the centre of the bitmap.
        PointF[] corners = new PointF[]{
            new PointF(-wOver2, -hOver2),
            new PointF(+wOver2, -hOver2),
            new PointF(+wOver2, +hOver2),
            new PointF(-wOver2, +hOver2)
        };

        for (int i = 0; i < 4; i++) {
            PointF p = corners[i];
            PointF newP = new PointF((float)(p.X * Math.Cos(radians) - p.Y * Math.Sin(radians)), (float)(p.X * Math.Sin(radians) + p.Y * Math.Cos(radians)));
            corners[i] = newP;
        }

        // Find the min and max x and y coordinates.
        float minX = corners[0].X;
        float maxX = minX;
        float minY = corners[0].Y;
        float maxY = minY;
        for (int i = 1; i < 4; i++) {
            PointF p = corners[i];
            minX = Math.Min(minX, p.X);
            maxX = Math.Max(maxX, p.X);
            minY = Math.Min(minY, p.Y);
            maxY = Math.Max(maxY, p.Y);
        }

        // Get the size of the new bitmap.
        SizeF newSize = new SizeF(maxX - minX, maxY - minY);
        // ...and create it.
        Bitmap returnBitmap = new Bitmap((int)Math.Ceiling(newSize.Width), (int)Math.Ceiling(newSize.Height));
        // Now draw the old bitmap on it.
        using (Graphics g = Graphics.FromImage(returnBitmap)) {
            g.TranslateTransform(newSize.Width / 2.0f, newSize.Height / 2.0f);
            g.RotateTransform(Angle);
            g.TranslateTransform(-b.Width / 2.0f, -b.Height / 2.0f);

            g.DrawImage(b, 0, 0);
        }

        return returnBitmap;
    }

【讨论】:

  • 非常感谢,您让我的一天感觉好多了。你是个天才。谢谢人
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多