如何保持图像';在C#中旋转后的s质量?
我的讲师要求我编写一个程序,可以旋转图像,而无需C#library提供任何转换函数,这意味着我可以使用C#library提供的方法。我的问题是,旋转后,图像的质量变得非常差,如下图所示 这是我的代码,第一部分是为旋转后的图像创建一个新位图:如何保持图像';在C#中旋转后的s质量?,c#,image,rotation,C#,Image,Rotation,我的讲师要求我编写一个程序,可以旋转图像,而无需C#library提供任何转换函数,这意味着我可以使用C#library提供的方法。我的问题是,旋转后,图像的质量变得非常差,如下图所示 这是我的代码,第一部分是为旋转后的图像创建一个新位图: double sin = Math.Abs(Math.Sin(ratio * (Math.PI / 180.0))); double cos = Math.Abs(Math.Cos(ratio * (Math
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));
}
}
}
int intHeight=bitmapOri.Height;
int intWidth=bitmapOri.Width;
双x_cen=intWidth/2.0;
双y_cen=八分之一/2.0;
不安全的
{
对于(intj=0;j=位图宽度| y|u new>=位图高度)
继续;
bitmapRes.SetPixel((int)x_new,(int)y_new,bitmapOri.GetPixel(j,i));
}
}
}
您能告诉我我的代码中有什么欺诈,有什么问题吗?非常感谢您的帮助。问题
double to int操作可能会导致某些像素设置多次,而某些像素未设置
解决方案
反其道而行之
旋转时,需要考虑高宽比。如果您将一个4宽3高的图像旋转90度而不进行调整,则最终会将4挤压成3,并将3扩展成4。因此,要么调整旋转的方式,要么找出旋转图像所在对象的方式,而不是图像本身。问题的根源在于你的铸造。当您围绕原点旋转一个点时,该点在绝大多数情况下都会产生一个十进制数,但当您将坐标转换为(int)时,您将丢弃该信息。这会导致某些像素多次设置,而其他像素则根本没有设置。简单的解决方案是舍入而不是截断,但ZenWu的答案中有一个更稳健的解决方案。作为旁注,您也在
不安全的块中操作,但您的代码都不要求如此。另一个问题。当图像没有通过其中心旋转时,我的旋转函数会发生什么情况?第三步的技术术语是“双线性插值”。哪一个公式可以帮助我在第二步中找到原始图像上的位置?@iamatsundere181只是公式的反向函数,可能你自己尝试一下,因为这是一个练习另一个问题。当图像没有通过其中心旋转时,我的旋转函数会发生什么情况?@iamatsundere181很抱歉,我没有真正检查你的旋转公式。我编辑了答案并添加了一些关于步骤2的细节。还提到了旋转枢轴