2009-04-15 105 views
0

我有3位图点。什么是在另一幅图像上绘制图像的最快方式?

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尽可能快。任何人都可以给我一些样品吗? 非常感谢!

感谢unwind的回答。我写了下面的代码:

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

这部分需要968ms ......实在是太慢了......

+0

是bottoLayer尺寸总是一样的totalCanvas尺寸? 如果是这样,为什么创建两个位图? – user88637 2009-04-15 07:28:13

+0

谢谢,我在问题中添加了原因。 – user25749 2009-04-15 08:15:15

回答

1

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

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

一个简单的例子:

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

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

这意味着你的副本应在1453愉快地运行FPS,这是我假定“足够好”。

0

如果可能(并且它看起来像来自您的代码),使用DrawImageUnscaled将比DrawImage快得多。或者如果你一遍又一遍地使用相同的图像,创建一个TextureBrush并使用它。

GDI +的问题是,大多数情况下,它是不加速的。为了获得快速的绘图速度,你真的需要GDI和BitBlt,这是一个严重的痛苦,但是与GDI +一起使用,特别是当你在托管代码中(很难判断你是否使用托管C++或直C++)。

有关在.net中快速显示图形的更多信息,请参阅此post

相关问题