c#中的无损位图旋转
本文关键字:位图 旋转 | 更新日期: 2023-09-27 18:06:58
我在一个表单应用程序中制作一款自上而下的赛车游戏(我知道这是非常无效的,但这是一个学校项目,老师说只能是表单应用程序)。我有一个小车位图,我想把它旋转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));