java - BufferedImage 与 VolatileImage 的当前状态

标签 java graphics bufferedimage

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

我到处都读到 VolatileImage 是硬件加速的,而 BufferedImage 是管理的,除了可能不再是因为随着每个新更新(+ Java 7 的发布),随着 Java 加速更多和更多的 BufferedImage 等等,等等。

那么(一般而言)您对在这些条件下实现快速图像绘制有什么建议:

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

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

最佳答案

来 self 移动的线程“BufferedImage 与 VolatileImage - 性能比较”(已编辑和改进):

介绍

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


基准测试

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

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

结果:我在配备 Intel i5 双核 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 似乎并没有像 BufferedImage 那样损失那么多速度,尽管添加了一个 alpha channel 。

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

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

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


来源

我上传了我的 source code on GitHub .大家可以看一下,想拉拉自己试试!

关于java - BufferedImage 与 VolatileImage 的当前状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11514929/

相关文章:

javascript - 为什么变换会移动整个坐标系而不是仅仅移动 SVG 中的元素?

c# - WPF/C#画半圆/半圆

java - 读取和写入大图像

java - 尝试添加棉花糖权限支持时无法解析符号 'LocationService'

java - 查找集合的所有子集 (PowerSet)

java - 当路径有空间时使用批处理循环构建类路径时出现问题

Java - 不能扩展类?

java - eclipse中的maven在哪里?

c++ - 在 gDebugger 中运行我的程序时出现奇怪的结果

java - 通过java中的套接字发送屏幕截图(bufferedImage)