C#快速结合位图用于UI

时间:2011-05-23 17:26:28

标签: c# performance image user-interface

基本上我是从头开始创建一个动画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)?如果所有其他方法都失败了,我想我可以找到一种方法来只绘制已经改变的部分,但是我希望避免这样做,如果蛮力重绘一切都是可能的。非常感谢!

2 个答案:

答案 0 :(得分:1)

逐像素方法是您可以做的最差的方法。相反,你应该描述你的应用程序这很简单:在完全工作负载(100%cpu)下运行它并暂停调试器10次。看看它停在哪里,这是你必须优化的热点。

答案 1 :(得分:1)

您永远不应该使用位图来绘制实时动画。只需创建一个CustomControl,并像这样覆盖它的OnPaint方法

protected override void OnPaint(PaintEventArgs pe)
{
}

你可以使用pe.Graphics进行你想要的任何绘图,不需要复制到屏幕。 我已经习惯了,如果你的绘图程序相当快,那就很顺利了。

另外,请记住在控件构造函数中调用SetStyle(ControlStyles.OptimizedDoubleBuffer, true);以获得双缓冲