我的讲师要求我编写一个可以旋转图像的程序,而不需要C#库提供的任何转换功能,这意味着我可以使用this wiki's link提供的方法。我的问题是,旋转后,图像的质量变得非常糟糕,如下图所示。
这是我的代码,第一部分是在旋转后为图像创建一个新的位图:
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));
}
}
}
您能告诉我代码中的欺诈行为是什么,它有什么问题,非常感谢您的帮助。
答案 0 :(得分:1)
double to int操作可能会导致某些像素设置超过一次而某些像素未设置
尝试相反的方式
如何计算原始图像中的位置
让旋转轴为O,将A点视为目标图像中的像素
OA 可写为t * rotate(alpha, OX )。 OX 是从点O开始的归一化向量。这意味着 OA 向量可以被视为(或通过)旋转 alpha 角度来自< strong> OA ,它可以有一个特殊的长度( t )。并且 OA 实际值将是(t * cos(alpha),t * sin(alpha))
假设OA实际上是旋转OB,因为它是从原始图像旋转的目标图像,所以OB可以写成t * rotate(alpha + beta, X )。这意味着 OA 是 OB 之间不同的一个旋转操作。这有点奇怪。但这是正确和有用的。
让我们现在做真正的工作。 OB 实际值为(t * cos(alpha + beta),t * sin(alpha + beta))。
让我们关注X坐标,它等于t * cos(alpha)* sin(beta)+ t * sin(alpha)+ t * cos(beta),然后转回观看 OA 协调。它推断X( OB )= sin(beta)* X( OA )+ cos(beta)* Y( OA )。 Y坐标是相同的。