基本上我是从头开始创建一个动画UI。 UI上的所有内容都是从ScreenThing基类派生的,它可以存储用于绘制该东西的位图及其位置。当我想绘制UI时,我创建了一个正确大小的新空白位图,从该位图创建一个Graphics对象,然后将该Graphics对象传递给所有ScreenThings Draw()方法来绘制自己。完成后,我使用PictureBox控件将位图打印到屏幕上。
这一切都很好,但速度太慢了。我希望这种情况每秒至少发生30次,因此动画很流畅,但所有这一切都需要超过33毫秒。我已经看到这种缓慢的原因是锁定和解锁位图内存。我尝试了一些我在网上找到的解锁位图的代码并创建了一个新的GetPixel和SetPixel函数,并尝试像下面一样逐像素地组合图像,但这需要更长的时间。 (下面的代码只是一个测试,它不会将图像放在正确的位置)
for (int i = 0; i < images.Count; i++)
{
FastBitmap foreground = new FastBitmap(images[i]);
foreground.LockImage();
for (int x = 0; x < images[0].Width; x++)
{
for (int y = 0; y < images[0].Height; y++)
{
output.SetPixel(x, y, foreground.GetPixel(x, y));
}
}
foreground.UnlockImage();
}
那么最好的方法是什么?是否可以像这样使用C#实时绘制一个非常大的图像(如1024x768)?如果所有其他方法都失败了,我想我可以找到一种方法来只绘制已经改变的部分,但是我希望避免这样做,如果蛮力重绘一切都是可能的。非常感谢!
答案 0 :(得分:1)
逐像素方法是您可以做的最差的方法。相反,你应该描述你的应用程序这很简单:在完全工作负载(100%cpu)下运行它并暂停调试器10次。看看它停在哪里,这是你必须优化的热点。
答案 1 :(得分:1)
您永远不应该使用位图来绘制实时动画。只需创建一个CustomControl,并像这样覆盖它的OnPaint方法
protected override void OnPaint(PaintEventArgs pe)
{
}
你可以使用pe.Graphics进行你想要的任何绘图,不需要复制到屏幕。 我已经习惯了,如果你的绘图程序相当快,那就很顺利了。
另外,请记住在控件构造函数中调用SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
以获得双缓冲