The PNGDecoder class is available as a stand alone JAR file and is below 10KB in size.
The usage of this PNG decoder is very simple:
Let's analyze this code step by step.
This decodes the header of the PNG files and extracts information like width, height and color format. If the input stream is not a valid PNG file then an IOException is thrown. The following methods can be used to retrieve information about the PNG:
This will decode the image data of the PNG. First we need to allocate a ByteBuffer. In this case we want to decode the PNG as RGBA image which uses 4 bytes per pixel. The PNGDecoder has a stride parameter which specifies the distance in bytes from the start of a line to the start of the next line. In this case we set it equal to the number of bytes per line. It will write to the specified ByteBuffer starting at the current position.
On return the position will be after the last written byte. If we specified a stride lager then the line length then this additional space is not included in the buffer position.
If the remaining space in the ByteBuffer is not enough then a BufferOverflowException will be thrown.
The resulting ByteBuffer can then directly be used to upload the tetxure to OpenGL like this:
import de.matthiasmann.twl.utils.PNGDecoder; .... InputStream in = new FileInputStream("white_pixel.png"); try { PNGDecoder decoder = new PNGDecoder(in); System.out.println("width="+decoder.getWidth()); System.out.println("height="+decoder.getHeight()); ByteBuffer buf = ByteBuffer.allocateDirect(4*decoder.getWidth()*decoder.getHeight()); decoder.decode(buf, decoder.getWidth()*4, Format.RGBA); buf.flip(); while(buf.hasRemaining()) { System.out.printf("%02X\n", buf.get() & 255); } } finally { in.close(); }
PNGDecoder decoder = new PNGDecoder(in);- getWidth
- getHeight
- hasAlpha - returns true if this PNG has either an alpha channel or uses a transparent color
- isRGB - returns true if this PNG is either true color or uses a palette, and false if it's gray scale
- decideTextureFormat - adjust the requested color format based on the PNG and the capabilities of the decoder
ByteBuffer buf = ByteBuffer.allocateDirect(4*decoder.getWidth()*decoder.getHeight()); decoder.decode(buf, decoder.getWidth()*4, Format.RGBA); buf.flip();
GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA, decoder.getWidth(), decoder.getHeight(), 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, buf);
on 2010/12/01 12:53