12

我正在尝试创建一个快速的图像生成器,它可以进行大量的 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 以保存,因为我的图像非常大,我会遇到内存不足的问题......

4

3 回答 3

6

根据我的调查和阅读 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 提供提示。您可以在 Java 教程的 2D 跟踪中阅读此内容。

于 2010-03-11T16:52:59.087 回答
1

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

-Dsun.java2d.accthreshold=0

编辑

在您说上述方法无效后,我对此进行了一些阅读。尝试将 OpenGL 参数上的True更改为全部小写。

-Dsun.java2d.opengl=true
于 2010-03-03T20:20:15.363 回答
0

下面是它的工作原理:

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

-Dsun.java2d.accthreshold=0

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

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

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

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

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

于 2010-03-06T13:48:14.350 回答