开发者

How can I create a hardware-accelerated image with Java2D?

开发者 https://www.devze.com 2022-12-22 06:44 出处:网络
I\'m trying to create a fast image generator that does lots of 2d transformations and shape rendering, so I\'m trying to use a BufferedImage and then acquire the Graphics2D object to perform all my dr

I'm trying to create a fast image generator that does lots of 2d transformations and shape rendering, so I'm trying to use a BufferedImage and then acquire the Graphics2D object to perform all my drawing. My main concern now is to make is really fast so I'm creating a BufferedImage like this:

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

However if I do:

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

The output is always false, even if I start the JVM with -Dsun.java2d.opengl=True which prints the line:

OpenGL pipeline enabled for default config on screen 0

I'm doing a BufferedImage because in the end I want to save it to a PNG file with ImageIO.write(bImage, "PNG", file);

I can create a VolatileImage which will say that it is accelerated but ImageIO doesn't like it when trying to save, saying that that image cannot be casted to RenderedImage. Any 开发者_开发知识库ideas on how to get an accelerated image that can be stored to disk? Also I don't want to create a VolatileImage and the copy to a BufferedImage to save since my images are really big and I'll run into out of memory issues...


From my investigation and reading the Sun/Oracle 2D tutorial this is what I've found:

To create an accelerated image one can either use the volatile image, which is created as a pbuffer. There are advantages and disadvantages, VolatileImages are fast until you try to get the raster pixel data. At that moment they become a normal bufferedImage. Also they are volatile and there is no guarantee that it will be available in the end of your rendering. To do this you execute:

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

This will get you a accelerated image, however it is not possible to use the ImageIO to write it directly to say a PNG file.

In order to use a normal BufferedImage you need to do something like:

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

This creates a BufferedImage which is not accelerated but you give the hint to the JVM that is should by passing 1 in setAccelerationPriority. This you can read on the 2D trail of the Java Tutorial.


Try adding this to your command line:

-Dsun.java2d.accthreshold=0

EDIT

I did some reading on this after you said the above didn't work. Try changing the True on the OpenGL parameter to be all lowercase.

-Dsun.java2d.opengl=true


Here is how it works:

The way you create the image is correct. But Java does not accelerate the image right away. There is a threshold of render calls that need to be directed at your image after which the image will be accelerated. But if you set the following,

-Dsun.java2d.accthreshold=0

your image should be accelerated the moment you create it.

You might still have to use the image somehow for it to become accelerated. For example, i have the following code piece that is used to copy a loaded image (loading through ImageIO will give you an image that can not be accelerated) into my new BufferedImage.

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

Before this code segment, the BufferedImage is not accelerated, afterwards it is.

But beware, if you manipulate the image data directly (i.e. not through Java-2d) your image will no longer be cached in VRAM and you have to copy it over to a new Managed Image in order to regain your acceleration.

0

精彩评论

暂无评论...
验证码 换一张
取 消