PNG and blit speed

I’m trying to use PNGs for my graphics, but I’ve come across a problem.

Java can blit opaque images very quickly. It can also do very well with transparent. It does not do a good job when the image is translucent.

I’m basing this on comments and code from David Brackeen’s book.

PNGs can use alpha values, ie translucency, or be completely opaque, or just use straight transparent the way GIFs do. So how do I know which way java is going to interpret the PNG?

Is there some easy way of checking?

Anyone have some advice?

Right now you should copy the images once in order to get acceleration. Like this:


BufferedImage i = ImageIO.read(new BufferedInputStream(getClass().getResourceAsStream(path)));
Graphics2D tg;
BufferedImage c = gc.createCompatibleImage(w,h,transparency);
tg = (Graphics2D)c.getGraphics();
tg.setComposite(AlphaComposite.Src);
tg.drawImage(i,0,0,null);
tg.dispose();

Were “tranparency” can be either Transparency.BITMASK, Transparency.OPAQUE or Transparency.TRANSLUCENT.

Once copied you’ll have that specific kind of BufferedImage for sure. Just use 1, 2, 4, or 8bit indexed images and there won’t be a problem (because most drawing programs simply don’t support rgba indexed images).

You can also just create gifs and convert em at the end to png files (eg with PNGOUT). This way you can only get BITMASKed images.

[quote] I’m basing this on comments and code from David Brackeen’s book.
[/quote]
I think Mister Brackeen’s comments are outdated and hurt java2d performance reputation.
what is your speed goal and machine target?
how many sprites would you want to blit with translucency?

Outdated? No, translucent images are still very slow if you don’t set that transaccel (or so) flag.

Ok, I think I am a tad confused about what PNGs are capable of. Looking through the PNG ‘home’ site didn’t make things more clear.

Can someone correct my understanding?

  • a 32bit PNG has Alpha, RGB

  • a 24bit has RGB and everything is considered opaque

  • a color indexed image may or may not have a transparent color and the indexes map to 24bit RGB colors. You get 256 different colors from the 24bit pallette.

  • Are there other combinations?

Regards,
Dr. A>

oNyx - The BITMASK type would be the ones with either fully opaque pixels or fully transparent, correct? If the source uses a range of Alphas, then which ones get set to opaque? IE - do the pixels with alphas > 127 become opaque and then ones less than that transparent?

Nutters, this is so much like when you go to school and then go try and do something only to realize you need lots more info ‘in the real world’ to apply what you learned.

Can there be two types of fully transparent-ness? IE - A 2 bit mask, which says either this pixel is opaque or not, regardless of the color stored there. And the other way being everything which is Purple is going to be transparent.

Are there other combinations?

Yes. But they don’t really matter (for game development at the time of writing). Eg 16bit grayscale or 48bit rgb… or 64bit rgba :o

The BITMASK type would be the ones with either fully
opaque pixels or fully transparent, correct?

Yes.

If the source uses a range of Alphas, then which ones get
set to opaque?

Depends on the programm, used for converting. I guess the majority would just trash the alpha information all together.

However, it’s also possible to use a RGBA indexed mode. Eg if you want 4 alpha “shades” for all colors you would end up with 64 different colors (each color needs index entries for 0%, 33%, 66% and 100% alpha). But that one is rarely used and, as I said, most tools don’t even support that (I’m wondering if ImageIO would handle that correctly).

Well, it’s easier to put the alpha stuff into a seperate image. Eg one opaque 256color (8bit) image and one 16 “color” (4bit grayscale) image for alpha. But… y’know… that would be somewhat slow in Java2D right now, because it’s more than simple bitmask stuff.

Just use gif for those images with (bitmask) transparency and convert em at the end to png with PNGOUT. Then compare sizes and pick the smaller one [usually png] :wink:

Sorry about not being clear on the transparency conversion. I meant what will Java do? If the source has a range of Alphas, when I set Transparency.BITMASK and then blit the image, which alphas go opaque? ???

which alphas go opaque?

Greater 127-ish :slight_smile:

The image:

on white:

on black:

copied over to a BITMASK image then blit and saved (as ARGB… because I’m lazy, but that’s the thing you would get in a game too):

Oh and the source:


import java.awt.*;
import java.awt.Image;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.*;
import javax.imageio.*;

public class BTTest
{
      public static void main(String[] args) throws IOException
      {
            GraphicsDevice device = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
            GraphicsConfiguration gc = device.getDefaultConfiguration();

            BufferedImage i = ImageIO.read(new BufferedInputStream(BTTest.class.getResourceAsStream("timg_tr.png")));
            Graphics2D tg;
            BufferedImage c = gc.createCompatibleImage(256,64,Transparency.BITMASK);
            tg = (Graphics2D)c.getGraphics();
            tg.setComposite(AlphaComposite.Src);
            tg.drawImage(i,0,0,null);
            tg.dispose();

            BufferedImage outImage = new BufferedImage(256,64,BufferedImage.TYPE_INT_ARGB);
            Graphics2D g2d = outImage.createGraphics();
            g2d.drawImage(c,0,0,null);

            g2d.dispose();

            try
            {
                  ImageIO.write(outImage, "png", new File("timg_bit.png"));
            }
            catch (IOException e)
            {
                  e.printStackTrace();
            }
      }
}

Ahh, yes! You are very wise Obi-Wan!

Thanks for making everything transparent! :wink:

Heh. To tell the truth… I hadn’t known the answer and decided to test it myself :wink:

But it’s really sweet that it’s like this. That allows you to add an nice quality switch in your games for speed/quality.Piece of a cake with (pre) rendered sprites.