Как я могу создать аппаратно-ускоренный образ с Java2D? - PullRequest
10 голосов
/ 03 марта 2010

Я пытаюсь создать быстрый генератор изображений, который выполняет множество двумерных преобразований и рендеринг фигур, поэтому я пытаюсь использовать 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.write (bImage, "PNG", file);

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

Ответы [ 3 ]

4 голосов
/ 11 марта 2010

Из моего исследования и прочтения учебника по Sun / Oracle 2D я нашел следующее:

Для создания ускоренного изображения можно использовать изменчивое изображение, которое создается как pbuffer. Есть преимущества и недостатки, VolatileImages работает быстро, пока вы не попытаетесь получить растровые данные пикселей. В этот момент они становятся обычным bufferedImage. Также они изменчивы, и нет никаких гарантий, что они будут доступны в конце вашего рендеринга. Для этого вы выполните:

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 .

1 голос
/ 03 марта 2010

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

-Dsun.java2d.accthreshold=0

РЕДАКТИРОВАТЬ

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

-Dsun.java2d.opengl=true
0 голосов
/ 06 марта 2010

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

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

-Dsun.java2d.accthreshold=0

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

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

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

До этого сегмента кода BufferedImage не ускоряется, а затем -.

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

...