【问题标题】:C# combine bitmaps fast for UIC# 为 UI 快速组合位图
【发布时间】:2011-05-23 17:26:27
【问题描述】:

基本上,我是从头开始制作动画 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)?如果所有其他方法都失败了,我想我可以找到一种方法来仅绘制已更改的部分,但如果可以对所有内容进行强力重绘,我很乐意避免这样做。非常感谢!

【问题讨论】:

  • 您是否有任何理由不将图像绘制到位图上,而不是使用逐像素的方法?

标签: c# performance image user-interface


【解决方案1】:

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

protected override void OnPaint(PaintEventArgs pe)
{
}

在那里,您可以使用 pe.Graphics 进行任何您想要的绘图,并且不需要复制到屏幕上。 我用过,如果你画的套路相当快,那会很流畅。

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

【讨论】:

  • 听起来是最好的方法。发布后,我记得曾经用 XNA 框架做这样的事情来在表单应用程序中显示 3d 模型。我打算在 XNA 中将其视为“2d 游戏”,但我将首先研究您的方法。谢谢!
【解决方案2】:

逐像素方法是您能做的最糟糕的方法。相反,您应该分析您的应用程序。这很简单:以满负荷运行(100% cpu)并暂停调试器 10 次。看看它停在哪里,那是你必须优化的热点。

【讨论】:

  • 简单地使用一个可以准确显示程序在哪里花费了多少时间的分析器怎么样?
  • 更好!你只需要拥有一个。调试器始终存在。
  • 我有一种逐像素的感觉是最糟糕的,但是在graphics.DrawImage方法太慢之后觉得值得一试。感谢您提供有关分析的提示,我以前从未尝试过,并将对其进行研究。
猜你喜欢
  • 2014-12-10
  • 2010-12-06
  • 1970-01-01
  • 2015-08-23
  • 1970-01-01
  • 2012-05-11
  • 2013-12-25
  • 2011-09-29
  • 1970-01-01
相关资源
最近更新 更多