[英]Lossless Bitmap rotation in C#
我正在用表单应用程序制作自上而下的Racing游戏(我知道这是极其无效的,但这是一个学校项目,老师说仅表单应用程序)。 我有一个汽车位图,想要将其旋转x度。 我找到了一种完全可以做到这一点的方法,但是我的问题是,经过几次旋转后,位图开始变得非常模糊并且严重影响了性能。 有没有一种方法可以使该算法更有效,并且不会成倍地降低质量?
这是旋转方法:
public Bitmap RotateImage(Image image, PointF offset, float angle)
{
float sin = (float)Math.Abs(Math.Sin(angle * Math.PI / 180.0));
float cos = (float)Math.Abs(Math.Cos(angle * Math.PI / 180.0));
float ImgWidth = sin * bmp.Height + cos * bmp.Width;
float ImgHeight = sin * bmp.Width + cos * bmp.Height;
Bitmap rotatedBmp = new Bitmap((int)ImgWidth,(int) ImgHeight);
Graphics g = Graphics.FromImage(rotatedBmp);
g.TranslateTransform(offset.X, offset.Y);
g.RotateTransform(angle);
g.TranslateTransform(-offset.X, -offset.Y);
g.DrawImage(image, new PointF(0, 0));
return rotatedBmp;
}
原始源图像旋转后,请勿覆盖。
将角度存储为绝对角度,而不是与上一个游戏帧的偏移量。
最后,每帧从头开始旋转原始源图像,然后绘制结果。
唯一的无损旋转是90度的倍数旋转。 在任何其他角度都不可能进行无损旋转。
编辑
另外,也不必将旋转图像的中间副本保留在其自己的缓冲区中。 您可以将旋转的汽车直接绘制到屏幕上。
如果我错了,而您绝对需要缓冲旋转汽车的图像,则可以只计算旋转图像所需的最大尺寸,然后重新使用缓冲区。 您可以通过计算对角线图像大小并将其用于宽度和高度,然后在该新缓冲区中居中绘制汽车来做到这一点。
像这样:(未经测试)
double maxSize = Math.Sqrt(bmpCp.Width * bmpCp.Width + bmpCp.Height * bmpCp.Height);
Bitmap rotatedBmp = new Bitmap((int)maxSize, (int)maxSize, pf);
//...
gBmp.DrawImage(bmpCp, new PointF((maxSize - bmpCp.Width) / 2.0,
(maxSize - bmpCp.Height) / 2.0));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.