• 12
• 11
• 9
• 10
• 13

# [java] Fastest Way to Draw Translucent Images

This topic is 4227 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hey everyone. I'm working on a 2D game that uses semi-transparent overlay images. The overlay images have 2 alpha values, 0 and 0.5. The code works and the images are drawn on top of my game board. However, its putting a lot of stress on my system when a lot of these images are displayed at once (if they are filling up half my screen, there is considerable lag). I think there is a faster way to draw my images, but I can't figure out what it is. Here is the code I use to load the images.
static BufferedImage getImage(String name) {
BufferedImage image;
try {
}
catch (Exception e) {
image = new BufferedImage(1,1,BufferedImage.TYPE_INT_ARGB);
}
return image;
}
The image is then drawn onto the screen using g.drawImage() . Any ideas on how I could speed this up? If anyone needs more information please let me know. Thanks!

##### Share on other sites
you could use opengl (LWJGL for example).

##### Share on other sites
Ideally I'd prefer to not use OpenGL or DirectX if possible...

##### Share on other sites
When I was working with Java2D there was a rather unique solution I found to this. I used an opaque BufferedImage the size of the screen that I would draw everything to (might have been volatile, not completely sure... sorry use LWJGL now), and then drawing this to the back buffer using an gfx.drawImage(img,0,0,null) call. The "gfx" reference was a Graphics2D obj that I got from a double-buffering BufferStrategy.

So simply its:
1: render everything to an opaque image acting as a fake back buffer (you might want to check image properties to ensure that it is opaque)
2: draw the image to the real back buffer

I was never completely sure why it worked better (very significantly actually, improving from 25 to 60 FPS) but I was using it to draw a translucent gradient across the bottom part of the screen in a full screen game. I think that it might do something different with the blending of translucency (perhaps calculating as each thing is rendered to the third buffer?). You might want to give it a try.

##### Share on other sites

for instance you could have an hashmap where the key is the file name and the value is the BufferedImage. The first time you call getImage for a specific file you will read it since it is not in the cache and after that you would fetch the reference to that already read image.

static Map cache = new HashMap();static BufferedImage getImage(String name) {  BufferedImage image = (BufferedImage )cache.get(name);  if( image == null)  {    try {      image = ImageIO.read(new File(name));    }    catch (Exception e) {      System.err.println("Error loading image file " + name + ".");      image = new BufferedImage(1,1,BufferedImage.TYPE_INT_ARGB);    }    cache.put(name,image);  }  return image;}

But if the image are really big and you have a lot you will run out of space pretty quickly. So I guess you might want to choose what you put in the cache(ie: frequently used image, small images).

##### Share on other sites
Also are you using -Dsun.java2d.translaccel=true?

##### Share on other sites
Make sure all source images you are drawing with are compatable with the surface you are drawing to. To do this, call createImage() on the component you are drawing on to get an image with the same properties. Then copy your loaded image to this new image. Keep the new image for drawing and discard the loaded image. Any image that is not format compatable to the surface you are drawing to will disable image acceleration.

##### Share on other sites
I have some problem, when i draw an opaque image is very fast, but when images are translucent all become very slow...
I managed my image whit this code:
public void optimizing(GraphicsConfiguration cfg) {
BufferedImage newBuffer=cfg.createCompatibleImage(imm.getWidth(),imm.getHeight(),imm.TRANSLUCENT);
Graphics2D bg2=newBuffer.createGraphics();
bg2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
bg2.drawImage(imm,0,0,null);
imm.flush();
imm=null;
imm=newBuffer;
bg2.dispose();
}

But draw translucent image are very slow anyway... whit -Dsun.java2d.translaccel=true is more slow...

There are any way?

##### Share on other sites
I have some problem, when i draw an opaque image is very fast, but when images are translucent all become very slow...
I managed my image whit this code:
public void optimizing(GraphicsConfiguration cfg) {		BufferedImage newBuffer=cfg.createCompatibleImage(imm.getWidth(),imm.getHeight(),imm.TRANSLUCENT);		Graphics2D bg2=newBuffer.createGraphics();		bg2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);		bg2.drawImage(imm,0,0,null);		imm.flush();		imm=null;		imm=newBuffer;		bg2.dispose();}

But draw translucent image are very slow anyway... whit -Dsun.java2d.translaccel=true is more slow...

There are any way?