Images and transparency: How does it work?

Hi!

During development of a simple 2D game engine I ran into a couple of questions regarding images.
[]What different image types (classes) are available in Java? I know of BufferedImage, VolatileImage and I have heard about some other hardware accelerated image type called automated image or something.
[
]If I make a gif image, which Java image types will support transparency? How do they support transparency? Do I have to specify what color is transparent etc.
[]Can I get transparency on jpeg images? How?
[
]Is automated images (sp?) the fastest way to do transparency? Is it handled automatically by the image if I want to draw it using Graphics or Graphics2D’s drawImage() methods?
I would really appreciate if someone could write a short explanatory article about images which explains the different concepts etc.

Thanks,

Johan Tibell

What different image types (classes) are available in Java? I know of BufferedImage, VolatileImage and I have heard about some other hardware accelerated image type called automated image or something.

Automatic Images (otherwise known as Managed Images), are images that are stored in main memory, and after several draw operations, will be cached in vram.

Automatic Images are the only way of getting hardware accelerated bitmask transparency.

There are only 3 classes you will need to worry about :-

  1. Image

The super class of all Images.
The Image reference returned from toolkit.getImage() and toolkit.createImage(URL or String) will be an automatic image.

  1. BufferedImage

BufferedImages created using any of the BufferedImage constructors will NOT be hardware accelerated.
BufferedImages returned from graphicsConfiguration.createCompatibleImage() will be elligable for hardware accleration as long as a direct reference to the images raster is never obtained.
(bufferedImage.getData())
Once this occurs, the image will no longer be cached in vram.

  1. VolatileImage

VolatileImages (obtained from graphicsconfiguration.createCompatibleVolatileImage() or component.createVolatileImage()) exist in vram only.
There is no copy of them in main memory.
if possible, VolatileImages will always be stored in vram (regardless of whether they are drawn or not)

If I make a gif image, which Java image types will support transparency? How do they support transparency? Do I have to specify what color is transparent etc.

No special code is required to create a transparent image.
The gif format itself provides for bitmask transparency.
As to how to achieve this, it varies between paint packages.

Can I get transparency on jpeg images? How?

no, the jpeg format has no support for transparency.
If you want >8bit images with transparency or translucency, use png.

Is automated images (sp?) the fastest way to do transparency? Is it handled automatically by the image if I want to draw it using Graphics or Graphics2D’s drawImage() methods?

automatic images (managed images) are the ONLY way of getting hardware accelerated transparency.

Johan Tibell
[/quote]

Thanks a bunch!

So the best solution if I use GIFs would be to load them Toolkit.createImage(filename) and then just use a drawImage() to draw them?

Thanks,

Johan Tibell

yep.

also, I should have said…

the BufferedImage returned from the javax.image.ImageIO.read(…) methods is NOT an automatic image.

Also, there is another alternative to using toolkit.createImage :-

public BufferedImage loadImage(URL image, int transparencyType)
{
   BufferedImage source = ImageIO.read(image);
   BufferedImage target = getGraphicsConfiguration().createCompatibleImage(source.getWidth(),source.getHeight(),transparencyType);
   target.getGraphics().drawImage(source,0,0,null);
   return target;
}

This method has 3 advantages :-

  1. unlike toolkit.createImage(), ImageIO.read() does not use asyncronous loading.

  2. the returned image is a BufferedImage (you might need the functionality provided by BufferedImage)

  3. images returned from toolkit.createImage() have a buggy ImageProducer.
    This manifests itself when using several of the image manipulation classes/methods, most notably image.getScaledInstance(…).
    The result can be a partially corrupt image.

Then do you think it might be a bug that both the following code (generated based on what you said) and also JComponent’s on a GeForce2Go in 1.4.1 for linux appear to be unaccelerated? (max of 50k semi-transparent pixels per second!).


GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
            GraphicsDevice gd = ge.getDefaultScreenDevice();
            GraphicsConfiguration gc = gd.getDefaultConfiguration();
            
            BufferedImage bi = gc.createCompatibleImage( getWidth(), getHeight() );
            Graphics g = bi.getGraphics();

…if so, this would explain why all my attempts to get decent speed out of transparent fillRect()'s are failing!

This does not look good…some rummaging produces:

For GraphicsDevice X11GraphicsDevice[screen=0]…
supported display modes: -1 @ 0
For GraphicsDevice X11GraphicsDevice[screen=1]…
supported display modes: -1 @ 0

(using:


      GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
      GraphicsDevice[] sd = ge.getScreenDevices();
            for( int k=0; k<sd.length; k++ )
            {
                  Logger.log( this, "DEBUG", "For GraphicsDevice "+sd[k]+"..." );
            DisplayMode[] dm = sd[k].getDisplayModes();
            for( int i=0; i<dm.length; i++)
            {
                  Logger.log( this, "DEBUG", "supported display modes: "+dm[i].getBitDepth()+" @ "+dm[i].getRefreshRate() );
            }
            }

Everything I said above is applicable to windows only.

Don’t ask me about the Linux implementation, I know naaaathing!

Does it have hardware acceleration at all??

btw, where you say

what do you mean?

Only bitmask transparency is hardware accelerated atm, translucency (full alpha channel) isn’t accelerated.

Though having said that, if you’re using 1.4.1_02 there are several properties you can set that enable hardware acceleration for AlphaCompositing & translucent images.

An explanation of the flags have been mentioned elsewhere in the forum, here they are for quick reference.


System.setProperty("sun.java2d.translaccel", "true");
System.setProperty("sun.java2d.ddforcevram", "true");
System.setProperty("sun.java2d.trace", "count");
System.setProperty("sun.java2d.accthreshold", "0");

[quote]Everything I said above is applicable to windows only.

Don’t ask me about the Linux implementation, I know naaaathing!

Does it have hardware acceleration at all??
[/quote]
Well, this is the problem - who knows? The 1.4 release notes has a “linux specific” section, which mentions nothing about graphics, and I can’t find any section of the release notes that talks about hardware accelerated (or not!) images.

If, as is beginning to seem more likely, linux has only partial hardware acc in addition to not having fullscreen mode, then WTF is the 1.4.1 release on linux? With partially unimplemented API’s it sounds more like it’s “1.4.0 beta 2” and that there isn’t a real gold release for linux yet…I appreciate getting “early access” to technologies, but not at the cost of going back to the bad old days of Java 1.0 and 1.1, where lots of platforms had partial implementations, and so you ended up having to recode for different VMs.

I’m sorry but I don’t understand the difference…do you know any links to places where I could find a detailed explanation? (or do you know where in the javadocs I should look?)

Thanks.

with bitmask transparency the alpha can be 1 of only 2 values.
Totally transparent (alpha of 0)
Totally opaque (alpha of 1).

try looking at the java.awt.Transparency interface.

Searching for any of those properties, e.g:

sun.java2d.ddforcevram

on YABB only shows up this thread. Ditto for “translucency”. “transparency” finds some threads in the LWGJL topic, but that’s about it.

Sorry about this, but can you remember which topics this has come up in before? Maybe the YABB search isn’t working properly, I don’t know.

Thanks

The YABB search defaults to only searching the previous 7days of posts, you have to manually tell it to include more days.

Try 60.

[quote]The YABB search defaults to only searching the previous 7days of posts, you have to manually tell it to include more days.

Try 60.
[/quote]
LOL. Thanks. “Problem exists between keyboard and chair”. Found the thread you were thinking of - and the depressing news that linux won’t get fullscreen support until probably Java 1.6 !!! ("…about changing display modes and such [in linux], then no, unfortunately, we don’t have bandwidth to work on this for 1.5")

…and no hardware trans(whatever :)) support until 1.5. Sigh. Guess I just stop working for a year or two (!) - or switch to C++ (if I’m writing Windows-only programs anyway, then…)

[quote]Guess I just stop working for a year or two (!) - or switch to C++ (if I’m writing Windows-only programs anyway, then…)
[/quote]
I call Troll!