在实现窗口快速图像绘制方面,当前的最佳实践是什么?我说的是一些非常简单的东西,比如一个具有2缓冲区策略的JFrame。(目前)最快的方法是什么?
我到处都读到VolatileImage是硬件加速的,而BufferedImage是管理的,只是可能不再是这样了,因为随着每一次新的更新(+Java 7的发布),随着Java对BufferedImage等的加速越来越多,情况可能不再如此。
那么(一般来说)你对在这些条件下实现快速图像绘制有什么建议:
- Java 6u33+或Java 7+
- 一个图像覆盖整个JFrame或多个小图像
- 图像透明度可以启用也可以不启用,但必须足够容易地得到支持
- 如果它有助于思考使用活动渲染的类似游戏循环的设置
在有人问我之前,我已经尝试过对这两个进行基准测试,我发现我的硬件几乎没有什么不同。然而,我听说这可能也依赖于硬件,所以我真的只是在寻找现代最佳实践。
从我移动的线程"BufferedImage vs VolatileImage-性能比较"(经过编辑和改进):
引言
我最近在JavaGaming.org上发现了一篇关于VolatileImage的帖子,与BufferedImage相比,它的性能非常棒。我在我的一个项目中亲自尝试过,它的优势似乎很明显!但尽管我很挑剔,但我想以数字的形式看到结果,这就是我想到的:
基准
我决定创建一个小程序,为我提供一些基准结果,以比较不同条件下的两种图像类型。
程序:基准方法很简单。2K(2560x1440)测试图像被缩小到HD(1280x720),然后绘制到BufferedImage或VolatileImage上(我使用BufferedImage来存储测试图像,因为测试表明,我使用什么图像类型来存储它没有区别)。然后有两种变体:1st当测试图像被绘制到Buffered或VolatileImage时,Buffered或VolatileImage在同一循环中被绘制到帧的JPanel。2nd测试图像在绘制到JPanel之前,在Volatile或BufferedImage上绘制了n次。该程序记录两个测试(第一个BufferedImage,第二个VolatileImage)的执行时间,并在控制台中打印出来。我还测试了如果你使用相同的测试图片和alpha通道(透明度),结果会如何,因为我经常看到有人声称VolatileImage的会有问题。
结果:我在Mac Minit(2012年末)上运行了该程序,该程序的英特尔i5双核处理器为2.5Ghz。使用的Java版本为v8_112,通过Eclipse执行。以下是我的结果:
Test-methodology 1 - no transparency:
Num of Repeats: BufferedImage: VolatileImage:
200 3.280 Seconds 0.784 Seconds
500 8.230 Seconds 1.818 Seconds
1000 16.030 Seconds 3.666 Seconds
Test-methodology 1 - transparancy:
Num of Repeats: BufferedImage: VolatileImage:
200 4.166 Seconds 0.806 Seconds
500 10.636 Seconds 1.793 Seconds
1000 20.565 Seconds 3.514 Seconds
Test-methodology 2 - no transparancy:
Num of Repeats: BufferedImage: VolatileImage:
200 1.165 Seconds 0.093 Seconds
500 2.862 Seconds 0.104 Seconds
1000 5.770 Seconds 0.112 Seconds
Test-methodology 2 - transparancy:
Num of Repeats: BufferedImage: VolatileImage:
200 2.389 Seconds 0.120 Seconds
500 5.986 Seconds 0.128 Seconds
1000 11.902 Seconds 0.134 Seconds
结论
当然,性能在很大程度上取决于图像的实现和使用方式。在我的情况下,作为缓冲区,允许我做一些事情,比如随着整个图像的褪色。但是,你仍然可以发现这两种图像类型的一些显著的缺点和优点:
一般来说,VolatileImage在测试中似乎比BufferedImage快得多(4到6倍)。当我在一个小游戏中使用相同的实现时,在一个非合成测试中得到了类似的结果。但在我的测试中,我发现了一种实现方式(遗憾的是,我无法重建它),它向我表明,VolatileImage并不是一直走的路(是的,在这种情况下,它比它的竞争对手慢)。
从透明度来看,两种图像类型的缩放都是均匀的,但VolatileImage似乎没有像BufferedImage那样损失太多速度,尽管添加了alpha通道。
我想提的是:在我的循环运行次数较少(1-10)的测试中,我发现BufferedImage在绘制单个帧时要快得多。尤其是在渲染透明图像时。单个帧占用BufferedImage大约0.03秒,VolatileImage需要0.035秒。当使用大约3到6次循环运行时,差距变得更大。VolatileImage仅在8比10的时候就占据了上风,并且随着循环次数的增加而变得更好。。。
我想用你的观点(由测试支持)来扩展这个结论,还想知道你提出了这两个图像的哪些实现,以及它们是如何变化的
就我个人而言,我将在未来使用VolatileImage进行渲染。BufferedImage将是我的日常驱动程序,用于存储在渲染循环中绘制的图像。主要是因为我发现它们更容易处理(有一种方法可以将BI转换为VI,但这是另一个时代的故事)。我还期待着Java9,它已经在今年12月发布,但似乎被推迟了,它将再次运行我的测试。
来源
我在GitHub上传了我的源代码。你可以看看它,如果你想的话,就自己动手试试!
是否有任何官方文件或基准可以帮助证明这一点?
我不知道。但是,您可能会修改这个Java2D基准测试来比较这两种方法:http://www.randelshofer.ch/oop/graphics/index.html
(关于Java基准测试的标准注意事项适用…)