在另一张图像上绘制图像的最快方法是什么?

时间:2009-04-15 07:12:00

标签: gdi+ performance drawimage

我有3个Bitmap点。

Bitmap* totalCanvas = new Bitmap(400, 300, PixelFormat32bppARGB);  // final canvas
Bitmap* bottomLayer  = new Bitmap(400, 300,PixelFormat32bppARGB); // background
Bitmap* topLayer = new Bitmap(XXX); // always changed. 

我将在bottomLayer上绘制复杂的背景。我不想一次又一次地在totalCanvas上重绘复杂的背景,所以我将它存储在bottomLayer中。

TopLayer频繁更换。 我想将bottomLayer绘制为totalCanvas。哪种方法最快?

Graphics canvas(totalCanvas); 
canvas.DrawImage(bottomLayer, 0, 0);  step1
canvas.DrawImage(topLayer ,XXXXX);   step2

我希望step1尽可能快。谁能给我一些样品? 非常感谢!

感谢放松的回答。我写了以下代码:

Graphics canvas(totalCanvas); 
for (int i = 0; i < 100; ++i)
{
canvas.DrawImage(bottomLayer, 0,0);
}

这部分花了968ms ......太慢了......

2 个答案:

答案 0 :(得分:1)

驱动程序应该实现几乎所有GDI +操作,以便在GPU上尽可能多地运行。这应该意味着一个简单的2D位图复制操作将“足够快”,即使是相当大的“足够”值。

我的建议是显而易见的:不要花时间寻找“最快”的方式来做这件事。你已经非常清楚地阐述了这个问题,所以只要按照你在问题中概述的那样清楚地实现它。那么你当然可以继续进行基准测试并决定继续寻找。

一个简单的例子:

  

32 bpp 400x300位图大小约为469 KB。根据{{​​3}},2002年的Nvidia GeForce 4 MX的理论内存带宽为2.6 GB / s。假设复制是在纯粹的“覆盖”模式下完成的,即没有混合现有表面(这听起来是正确的,因为您的副本基本上是将帧“清除”到副本的源数据的方式),并且开销因子为4为了安全起见,我们得到:

     

(2.6 * 2 ^ 30 /(4 * 469 * 2 ^ 10))= 1453

这意味着你的副本应该以1453 FPS运行,我很高兴地认为它“足够好”。

答案 1 :(得分:1)

如果可能的话(从代码中看起来很像),使用DrawImageUnscaled将比DrawImage快得多。或者,如果您反复使用相同的图像,请创建一个TextureBrush并使用它。

GDI +的问题在于,在大多数情况下,它是无法加速的。为了获得快速的快速绘图速度,你真的需要GDI和BitBlt,这是一个严重的痛苦,但与GDI +一起使用,特别是如果你使用托管代码(很难说你是使用托管C ++还是直接C ++)。 / p>

有关图形的更多信息,请参阅此post