【问题标题】:How can I create a hardware-accelerated image with Java2D?如何使用 Java2D 创建硬件加速映像?
【发布时间】:2011-01-23 09:04:05
【问题描述】:

我正在尝试创建一个快速的图像生成器,它可以进行大量的 2d 转换和形状渲染,因此我尝试使用 BufferedImage,然后获取 Graphics2D 对象来执行我的所有绘图。我现在主要关心的是制作速度非常快,所以我正在创建一个这样的 BufferedImage:

GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsConfiguration gc = ge.getDefaultScreenDevice().getDefaultConfiguration();
BufferedImage bImage = gc.createCompatibleImage(width, height, Transparency.TRANSLUCENT);
Graphics2D graphics = bImage.createGraphics();

但是如果我这样做:

System.out.println(bImage.getCapabilities(gc).isAccelerated());

输出始终为 false,即使我使用 -Dsun.java2d.opengl=True 启动 JVM 来打印该行:

OpenGL pipeline enabled for default config on screen 0

我正在做一个 BufferedImage,因为最后我想用 ImageIO.write(bImage, "PNG", file); 将它保存到一个 PNG 文件中;

我可以创建一个 VolatileImage,它会说它已加速,但 ImageIO 在尝试保存时不喜欢它,说该图像无法转换为 RenderedImage。关于如何获得可以存储到磁盘的加速图像的任何想法?此外,我不想创建 VolatileImage 并将副本复制到 BufferedImage 以保存,因为我的图像非常大,而且我会遇到内存不足的问题...

【问题讨论】:

  • 您使用的是什么版本的 Java?
  • 我在 Sun JDK 中使用 Java6
  • 我可以建议您实现代码,然后在代码到位后计时吗?这样你就可以计算出是否有足够的减速来保证尝试加速它。

标签: java performance image graphics java-2d


【解决方案1】:

根据我的调查和阅读 Sun/Oracle 2D 教程,这是我发现的:

要创建加速映像,可以使用作为 pbuffer 创建的 volatile 映像。有优点也有缺点,在您尝试获取光栅像素数据之前,VolatileImages 速度很快。在那一刻,它们变成了正常的缓冲图像。而且它们是易变的,并且不能保证它在渲染结束时可用。为此,您执行:

GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsConfiguration gc = ge.getDefaultScreenDevice().getDefaultConfiguration();
VolatileImage vImage = gc.createCompatibleVolatileImage(width, height, Transparency.TRANSLUCENT);

这将为您提供加速的图像,但是无法使用 ImageIO 直接将其写入到 PNG 文件中。

要使用普通的 BufferedImage,您需要执行以下操作:

GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsConfiguration gc = ge.getDefaultScreenDevice().getDefaultConfiguration();
BufferedImage img = gc.createCompatibleImage(width, height, Transparency.TRANSLUCENT);
img.setAccelerationPriority(1);

这会创建一个未加速的 BufferedImage,但您可以通过在 setAccelerationPriority 中传递 1 来向 JVM 提供提示。您可以在2D trail of the Java Tutorial 上阅读。

【讨论】:

    【解决方案2】:

    尝试将其添加到您的命令行:

    -Dsun.java2d.accthreshold=0
    

    编辑

    在您说上述内容不起作用之后,我对此进行了一些阅读。尝试将 OpenGL 参数上的 True 更改为全部小写。

    -Dsun.java2d.opengl=true
    

    【讨论】:

    • 添加该参数,不幸的是并没有改变任何东西。
    • 小写没有影响。从文档中,大写的 True 启用了带有调试信息的 OpenGL 管道,例如它打印:在屏幕 0 上为默认配置启用了 OpenGL 管道,使用小写字母,这是相同的行为,但没有打印出调试信息。
    • 我刚去谷歌搜索了一些关于这个的文档,这就是他们所说的。我想是为了帮助你不知道的事情而吸取的教训。
    【解决方案3】:

    这是它的工作原理:

    您创建图像的方式是正确的。但是 Java 不会立即加速图像。需要针对您的图像进行渲染调用的阈值,之后图像将被加速。但是如果你设置如下,

    -Dsun.java2d.accthreshold=0
    

    你的图像应该在你创建它的那一刻被加速。

    您可能仍需要以某种方式使用该图像才能使其加速。例如,我有以下代码片段,用于将加载的图像(通过 ImageIO 加载会给您一个无法加速的图像)复制到我的新 BufferedImage 中。

    Graphics2D g2d = bufferedImage.createGraphics();
    g2d.drawImage(image,0,0,null);
    g2d.dispose();
    

    在这段代码之前,BufferedImage没有加速,之后是。

    但请注意,如果您直接操作图像数据(即不通过 Java-2d),您的图像将不再缓存在 VRAM 中,您必须将其复制到新的托管图像才能重新获得加速。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-03-17
      • 1970-01-01
      • 2017-10-25
      • 2018-05-05
      • 2014-03-09
      • 2014-06-10
      • 2014-05-13
      相关资源
      最近更新 更多