[java] Transparent Images in awt

Started by
13 comments, last by tombr 18 years, 11 months ago
Hoy.

If you use BufferedImage, you really should consider using the raster data instead. (It's much faster than setting and getting single RGB values).

DataBufferInt dbuffer = (DataBufferInt)(((WritableRaster)image.getRaster()).getDataBuffer());int[] imageData = dbuffer.getData();


This gives you the int array imageData which is imageWidth*imageHeight in length. For bitmask images, the alpha value is either 0 or 1 (translucency is inbetween). 1 is opaque, 0 is transparent. Now, color mapping is I won't go into here, but to make a pixel transparent in imageData, simply imageData=0;
does the trick.

The big advantage with image.getRaster() is that the int array is directly mapped to the image (actual array, no copy). So any changes to the array, is reflected on the image itself. if you want an array like imageData, but not changes to it to reflect the image directly, use image.getData() (the same as getRaster() except this is a copy).

If you do not plan to mix and mess with colors at all, you can substitute the image.getRaster() with image.getAlphaRaster(). Note that not all ColorModel's support the alpha raster, so it will sometimes return null (the API is really self-explanatory).

It's just as well to learn how to use the raster right now, and learn it well. Once you understand it, it will make alot of stuff easiar for you.




Development blog, The Omega Sector -- http://www.omegasector.org
Advertisement
Well I guess it is only needed once to make an image transparent, and that is during the process of reading it from a file, which I guess happens during game initialization, when players are ready to wait for awhile. So it doesn't really matter if you use one way or another, but Addictman's method is certainly useful for effects I guess. But how do you know which color does imageData contains?
Well, it depends on your color model if you want to do it directly. But for a DirectColorModel (standard RGB with alpha),

From API:Number of bits:        32Red mask:              0x00ff0000Green mask:            0x0000ff00Blue mask:             0x000000ffAlpha mask:            0xff000000Color space:           sRGBisAlphaPremultiplied:  FalseTransparency:          Transparency.TRANSLUCENTtransferType:          DataBuffer.TYPE_INT


You can do the following:

int alpha = (pixels&0xff000000)>>24;int red   = (pixels&0x00ff0000)>>16;int green = (pixels&0x0000ff00)>>8;int blue  = pixels&0x000000ff;to convert back to packed color, do something likepublic static int ARGB(int r, int g, int b, int a){    return ( a << 24 ) | ( r << 16) | ( g << 8 ) | b;}for pixels that should be translucent or transparent,or simply public static int RGB(int r, int g, int b){    return ( 255 << 24 ) | ( r << 16) | ( g << 8 ) | b;}for opaque pixels.


Hope this helps.

[Edited by - Addictman on May 5, 2005 4:38:10 AM]
Development blog, The Omega Sector -- http://www.omegasector.org
As a sidenote, does anyone know if the following alpha scaling works always for DirectColorModels (default with GraphicsConfiguration.createCompatibleImage(..))

int alpha = ((c & 0xff000000)>>>24);


It *seems* (in my experiments) that this works. However, I am not sure if it can be trusted or not.
Development blog, The Omega Sector -- http://www.omegasector.org
Quote:Original post by Addictman
Hoy.

If you use BufferedImage, you really should consider using the raster data instead. (It's much faster than setting and getting single RGB values).

DataBufferInt dbuffer = (DataBufferInt)(((WritableRaster)image.getRaster()).getDataBuffer());int[] imageData = dbuffer.getData();


This gives you the int array imageData which is imageWidth*imageHeight in length. For bitmask images, the alpha value is either 0 or 1 (translucency is inbetween). 1 is opaque, 0 is transparent. Now, color mapping is I won't go into here, but to make a pixel transparent in imageData, simply imageData=0;
does the trick.

The big advantage with image.getRaster() is that the int array is directly mapped to the image (actual array, no copy). So any changes to the array, is reflected on the image itself. if you want an array like imageData, but not changes to it to reflect the image directly, use image.getData() (the same as getRaster() except this is a copy).

If you do not plan to mix and mess with colors at all, you can substitute the image.getRaster() with image.getAlphaRaster(). Note that not all ColorModel's support the alpha raster, so it will sometimes return null (the API is really self-explanatory).

It's just as well to learn how to use the raster right now, and learn it well. Once you understand it, it will make alot of stuff easiar for you.


Be aware that you don't always get DataBufferInt and if you don't check it's type, you'll end up with a ClassCastException. I've seen this on Images loaded with ImageIO on macs. So only get the raster when you know it's got the correct color model.

This topic is closed to new replies.

Advertisement