4

在将快速图像绘制到窗口时,当前的最佳实践是什么?我说的是一些非常简单的东西,比如一个带有 2 缓冲区缓冲区策略的单个 JFrame。(当前)最快的方法是什么?

我到处读到 VolatileImage 是硬件加速的,而 BufferedImage 是管理的,除了可能不再是因为每次新更新(+ Java 7 的发布),随着 Java 加速越来越多的 BufferedImage,情况可能不再如此等等等等。

所以(一般来说)你对在这些条件下实现快速图像绘制有什么建议:

  • Java 6u33+ 或 Java 7+
  • 一个图像覆盖整个 JFrame 或多个小图像
  • 可能会或可能不会启用图像透明度,但必须足够容易地支持
  • 如果它有助于考虑使用主动渲染的游戏循环设置

在有人问起之前,我已经尝试对这两者进行基准测试,但我发现我的硬件几乎没有差异。然而,我听说这也可能取决于硬件,所以我真的只是在寻找现代最佳实践。

4

2 回答 2

2

从我移动的线程“BufferedImage vs VolatileImage - PERFORMANCE COMPARISON”(编辑和改进):

介绍

我最近在 JavaGaming.org 上发现了一篇关于 VolatileImage 的帖子,与 BufferedImage 相比,它的性能非常出色。我自己在我的一个项目中尝试过,它的优势似乎很明显!但是我很挑剔,我想以数字的形式看到结果,这就是我想出的:


基准测试

我决定创建一个小程序,给我一些基准测试结果来比较不同条件下的两种图像类型。

程序:基准方法很简单。将 2K (2560x1440) 测试图像缩小到 HD (1280x720),然后绘制到 BufferedImage 或 VolatileImage 上(我使用 BufferedImage 存储测试图像,因为测试表明我使用什么图像类型来存储它没有区别) . 然后有两种变体: 第一个当测试图像被绘制到 Buffered- 或 VolatileImage 时,Buffered- 或 VolatileImage 在同一循环运行中被绘制到帧的 JPanel。 第二在将测试图像绘制到 JPanel 之前,它们会在 Volatile- 或 BufferedImage 上绘制 n 次。该程序记录两个测试(第一个 BufferedImage,第二个 VolatileImage)的执行时间并在控制台中打印出来。我还测试了如果您使用带有 alpha 通道(透明度)的相同测试图片,结果会如何,因为我经常看到有人声称 VolatileImage 会出现问题。

结果:我在配备 Intel i5 Dual Core 2.5Ghz 的 Mac Minit(2012 年末)上运行该程序。使用的 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 尽管添加了一个 alpha 通道,但似乎并没有像 BufferedImage 那样失去那么多的速度。

我想提一下:在循环运行次数较少(1-10)的测试中,我发现 BufferedImage 在绘制单帧时要快得多。尤其是在渲染透明图像时。单帧 BufferedImage 大约需要 0.03 秒,而 VolatileImage 需要 0.035。当使用大约 3 到 6 次循环运行时,差距变得更大。只有在超过 8 到 10 时,VolatileImage 才占据了主导地位,并且随着循环运行数量的增加而变得更好......

我想用您的意见扩展这个结论(由测试支持),并且还想知道您提出的这两个图像的哪些实现以及它们在那里的变化。

就个人而言,我将来会使用 VolatileImage 进行渲染。BufferedImage 将成为我存储图像的日常驱动程序,然后在我的渲染循环中绘制这些图像。主要是因为我发现它们更容易处理(有一种方法可以将 BI 转换为 VI,但这是另一个故事)。我也期待 Java 9,它已于今年 12 月宣布,但似乎被推迟了,并将再次运行我的测试。


资源

我在 GitHub 上上传了我的源代码。你可以看看它,如果你愿意,拉它自己试试!

于 2016-12-30T21:13:32.227 回答
0

是否有任何官方文档或基准可以帮助证明这一点?

不是我知道的。但是,您可以修改这个 Java 2D 基准来比较这两种方法: http ://www.randelshofer.ch/oop/graphics/index.html

(适用于 Java 基准测试的标准警告......)

于 2012-07-17T05:42:31.760 回答