【问题标题】:Properly rotate an image正确旋转图像
【发布时间】:2019-03-29 15:06:21
【问题描述】:

如何在不显示这样的情况下旋转图像?

这是我的旋转方法:

public static Bitmap RotateImageN(Bitmap bmp, float angle)
    {
        Bitmap rotatedImage = new Bitmap(bmp.Width, bmp.Height);
        using (Graphics g = Graphics.FromImage(rotatedImage))
        {
            // Set the rotation point to the center in the matrix
            g.TranslateTransform(bmp.Width / 2, bmp.Height / 2);
            // Rotate
            g.RotateTransform(angle);
            // Restore rotation point in the matrix
            g.TranslateTransform(-bmp.Width / 2, -bmp.Height / 2);
            // Draw the image on the bitmap
            g.DrawImage(bmp, new Point(0, 0));
        }

        return rotatedImage;
    }

编辑:尝试 Loocid 的代码后

【问题讨论】:

  • 搜索边界矩形
  • 你需要一个更大的结果位图或者你需要缩小源。

标签: c# image-processing


【解决方案1】:

您的rotatedImage 位图需要足够大以容纳旋转后的图像。

假设您将原始图像旋转了 30°,您需要像这样获得边界框的大小:

使用一些基本的触发:

x = L*cos(30 * π / 180) + w*cos(60 * π / 180)

y = L*sin(30 * π / 180) + w*sin(60 * π / 180)

因此将代码的开头更改为:

var x = bmp.Width * Math.Cos(angle * Math.PI / 180) + bmp.Height * Math.Cos((90-angle) * Math.PI / 180)
var y = bmp.Width * Math.Sin(angle * Math.PI / 180) + bmp.Height * Math.Sin((90-angle) * Math.PI / 180)
Bitmap rotatedImage = new Bitmap(x, y);

【讨论】:

  • 位图rotatedImage = new Bitmap(x, y);我猜
  • 基本上写的一样。 C# 有Math.SinMath.CosMath.PI
  • 如果我在 Draw Image 中使用它作为我的 x 和 y,它不会绘制。
  • 您是否将 30 和 60 更改为 angle90 - angle
  • @untargeted 我已更新我的答案以包含您需要使用的 C# 代码。这是假设angle 以度为单位。
【解决方案2】:

旋转中出现的问题与边界框有关。由于您提供的图像不适合您提供的区域,它正在剪裁边缘。

我也遇到过这个问题。所以我尝试了here的解决方案。

添加适合我的代码。

public static Bitmap RotateImageN(Bitmap bitmap, float angle)
{
    Matrix matrix = new Matrix();
    matrix.Translate(bitmap.Width / -2, bitmap.Height / -2, MatrixOrder.Append);
    matrix.RotateAt(angle, new System.Drawing.Point(0, 0), MatrixOrder.Append);
    using (GraphicsPath graphicsPath = new GraphicsPath())
    {
        graphicsPath.AddPolygon(new System.Drawing.Point[] { new System.Drawing.Point(0, 0), new System.Drawing.Point(bitmap.Width, 0), new System.Drawing.Point(0, bitmap.Height) });
        graphicsPath.Transform(matrix);
        System.Drawing.PointF[] points = graphicsPath.PathPoints;

        Rectangle rectangle = boundingBox(bitmap, matrix);
        Bitmap resultBitmap = new Bitmap(rectangle.Width, rectangle.Height);

        using (Graphics gDest = Graphics.FromImage(resultBitmap))
        {
            Matrix mDest = new Matrix();
            mDest.Translate(resultBitmap.Width / 2, resultBitmap.Height / 2, MatrixOrder.Append);
            gDest.Transform = mDest;
            gDest.DrawImage(bitmap, points);
            return resultBitmap;
        }
    }
}

private static Rectangle boundingBox(Image image, Matrix matrix)
{
    GraphicsUnit graphicsUnit = new GraphicsUnit();
    Rectangle boundingRectangle = Rectangle.Round(image.GetBounds(ref graphicsUnit));
    Point topLeft = new Point(boundingRectangle.Left, boundingRectangle.Top);
    Point topRight = new Point(boundingRectangle.Right, boundingRectangle.Top);
    Point bottomRight = new Point(boundingRectangle.Right, boundingRectangle.Bottom);
    Point bottomLeft = new Point(boundingRectangle.Left, boundingRectangle.Bottom);
    Point[] points = new Point[] { topLeft, topRight, bottomRight, bottomLeft };
    GraphicsPath graphicsPath = new GraphicsPath(points, new byte[] { (byte)PathPointType.Start, (byte)PathPointType.Line, (byte)PathPointType.Line, (byte)PathPointType.Line });
    graphicsPath.Transform(matrix);
    return Rectangle.Round(graphicsPath.GetBounds());
}

【讨论】:

  • 它现在不裁剪,但也不能完美旋转。
  • 请出示原图并告诉我旋转角度。
  • 原图:imgur.com/a/diglXEJ。旋转角度:52度
  • 它对我来说很好用。我想问题可能出在其他地方。在单独的 exe 中测试图像旋转,以便您了解。
  • 如何在图片框中绘制图像?
猜你喜欢
  • 2020-12-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多