如何在C#中旋转后保持图像的质量?

时间:2016-10-09 05:38:40

标签: c# image rotation

我的讲师要求我编写一个可以旋转图像的程序,而不需要C#库提供的任何转换功能,这意味着我可以使用this wiki's link提供的方法。我的问题是,旋转后,图像的质量变得非常糟糕,如下图所示。

the left hand side image is the origin

这是我的代码,第一部分是在旋转后为图像创建一个新的位图:

            double sin = Math.Abs(Math.Sin(ratio * (Math.PI / 180.0)));
            double cos = Math.Abs(Math.Cos(ratio * (Math.PI / 180.0)));
            bmpOut = new Bitmap((int)(sin * bmpIn.Width + cos * bmpIn.Height), (int)(sin * bmpIn.Height + cos * bmpIn.Width));

这是旋转图像的代码

        int intHeight = bitmapOri.Height;
        int intWidth = bitmapOri.Width;

        double x_cen = intWidth / 2.0;
        double y_cen = intHeight / 2.0;

        unsafe
        {
            for (int j = 0; j < intWidth; j++)
            {
                for (int i = 0; i < intHeight; i++)
                {
                    double x_new = x_cen + (double)((j - x_cen) * Math.Cos(ratio) - (i - y_cen) * Math.Sin(ratio));
                    double y_new = y_cen + (double)((j - x_cen) * Math.Sin(ratio) + (i - y_cen) * Math.Cos(ratio));
                    if (x_new < 0 || y_new < 0 || x_new >= bitmapRes.Width || y_new >= bitmapRes.Height)
                        continue;
                    bitmapRes.SetPixel((int)x_new, (int)y_new, bitmapOri.GetPixel(j, i));
                }
            }
        }

您能告诉我代码中的欺诈行为是什么,它有什么问题,非常感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

问题

double to int操作可能会导致某些像素设置超过一次而某些像素未设置

溶液

尝试相反的方式

  1. 旋转图像中的foreach像素
  2. 以原始图片计算其位置
  3. 如果位置不是整数,则按距离平均大约四个像素
  4. 细节

    如何计算原始图像中的位置

    1. 让旋转轴为O,将A点视为目标图像中的像素

    2. OA 可写为t * rotate(alpha, OX )。 OX 是从点O开始的归一化向量。这意味着 OA 向量可以被视为(或通过)旋转 alpha 角度来自< strong> OA ,它可以有一个特殊的长度( t )。并且 OA 实际值将是(t * cos(alpha),t * sin(alpha))

    3. 假设OA实际上是旋转OB,因为它是从原始图像旋转的目标图像,所以OB可以写成t * rotate(alpha + beta, X )。这意味着 OA OB 之间不同的一个旋转操作。这有点奇怪。但这是正确和有用的。

    4. 让我们现在做真正的工作。 OB 实际值为(t * cos(alpha + beta),t * sin(alpha + beta))。

    5. 让我们关注X坐标,它等于t * cos(alpha)* sin(beta)+ t * sin(alpha)+ t * cos(beta),然后转回观看 OA 协调。它推断X( OB )= sin(beta)* X( OA )+ cos(beta)* Y( OA )。 Y坐标是相同的。