Как создать аппаратно-ускоренное изображение с помощью Java2D?

Я пытаюсь создать быстрый генератор изображений, который выполняет множество 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, даже если я начну JVM с-Dsun.java2d.в OpenGL= "True", что печатает строка:

OpenGL pipeline enabled for default config on screen 0

Я делаю BufferedImage, потому что в конце концов я хочу сохранить его в PNG-файл с ImageIO.написать (bImage, "PNG", файл);

Я могу создать VolatileImage, который скажет, что он ускоряется, но ImageIO не нравится, когда пытается сохранить, говоря, что это изображение не может быть отлито для визуализации. Есть идеи о том, как получить ускоренный образ, который можно сохранить на диск? Также я не хочу создавать VolatileImage и копию в BufferedImage для сохранения поскольку мои изображения действительно большие, и у меня будут проблемы с памятью...

3 ответов


из моего исследования и чтения учебника Sun / Oracle 2D это то, что я нашел:

для создания ускоренного изображения можно использовать изменчивое изображение, которое создается как pbuffer. Есть преимущества и недостатки, 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, который не ускоряется, но вы даете подсказку JVM, которая должна, передавая 1 в setAccelerationPriority. Это вы можете прочитать на 2D след Java Учебник.


попробуйте добавить это в командную строку:

-Dsun.java2d.accthreshold=0

редактировать

Я прочитал об этом после того, как вы сказали, что выше не работает. Попробуйте изменить правда для параметра OpenGL все строчные буквы.

-Dsun.java2d.opengl=true

вот как это работает:

способ создания изображения является правильным. Но Java не ускоряет изображение сразу. Существует порог вызовов рендеринга, которые должны быть направлены на ваше изображение, после чего изображение будет ускорено. Но если вы установите следующее,

-Dsun.java2d.accthreshold=0

ваше изображение должно быть ускорено в момент его создания.

возможно, Вам все равно придется использовать изображение, чтобы оно стало ускоренным. Например, у меня есть следующий фрагмент кода, который используется для копирования загруженного изображения (загрузка через ImageIO даст вам изображение, которое нельзя ускорить) в мой новый BufferedImage.

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

перед этим сегментом кода BufferedImage не ускоряется, после этого он ускоряется.

но будьте осторожны, если вы управляете данными изображения напрямую (т. е. не через Java-2d), ваше изображение больше не будет кэшироваться в VRAM, и вам нужно скопировать его на новый управляемый образ, чтобы восстановить ускоряющий.