1
\$\begingroup\$

I googled around a bit and nobody seems to have asked this question.

I have images in multiple color formats (all of them are PNGs). Most of them are ARGB but my bitmap fonts are gray scale, and I would like them to stay that way. All I want to do is find out what format BufferedImage uses to store my pixel data and then use that information with glTexImage2D. Java, in all its wisdom, seems to be determined to hide that information from me at all costs...

I also need to know how BufferedImage aligns its pixel data in both of these formats (glTexImage2D cares).

Could someone please tell me how to:

  • Determine the pixel format of my BufferedImage. If it is ARGB32, I'm going to have to reorder the bytes and use GL_RGBA. If it's grayscale, I will be using GL_INTENSITY.
  • Extract the actual bytes from the image. I have seen a few examples on the web that use BufferedImage.getRaster().getDataBuffer(). This is nonsensical. Why are there different types of buffers like DataBufferInt? Because of Java's strong typing, I need DataBufferByte. If this is the only way, could somebody give me specific directions to use the different type of buffers with glTexImage2D?
  • Figure out how the aforementioned image data is aligned. I will use this information with glPixelStorei.

In addition, I come from C and C++ programming. In C this was 100 lines of simple libPNG and GL calls. Should I expect more trouble like this in the future?

\$\endgroup\$

1 Answer 1

0
\$\begingroup\$

It seems that BufferedImage does not keep that kind of information from the original PNG file. The type of the BufferedImage may or may not correlate with the type of the PNG. You can check the type of the BufferedImage with BufferedImage.getType(), which may help you, but the implementation of image loading is free to convert the images to other formats at will.

As you are comparing to C/C++ and libpng, I'll offer you an alternative solution. Use a similar low level library in Java as libpng. PNGJ: Java library for PNG encoding looks very promising. This gives you access to the actual PNG data instead of loading them to BufferedImages.

In addition, I come from C and C++ programming. In C this was 100 lines of simple libPNG and GL calls. Should I expect more trouble like this in the future?

Yes, you should always expect trouble when expanding to unfamiliar areas. And you will learn a lot when you do encounter those. Respectively a Java developer who has used to passing BufferedImages always as just RGBA data to OpenGL would be annoyed for needing to write 100 lines of low level code for that.

From my own experience I can tell that the biggest issue when moving from C++/OpenGL to LWJGL was the need to use java.nio buffers instead of arrays. See https://github.com/LWJGL/lwjgl3-wiki/wiki/1.5.-Bindings-FAQ for more information. Once I learned that, the transition was pretty straightforward.

\$\endgroup\$
2
  • \$\begingroup\$ I can create a BufferedImage using BufferedImage.TYPE_BYTE_GRAY and write to it using Graphics2D, and when I save that image with ImageIO, it is saved in gray scale format. Are you saying that there is no analogue for reading images in this fashion? \$\endgroup\$
    – user48979
    Jun 25, 2015 at 5:48
  • \$\begingroup\$ The format of BufferedImages more or less correlates with the created or loaded PNG files, but there is no guarantee about that and there is not much control over it. You can try using BufferedImage.getType() and it may work for you and even for everyone. But it definitely cannot tell the difference between 1, 2, 4 or 8 bit grayscale PNGs. \$\endgroup\$
    – msell
    Jun 25, 2015 at 6:21

You must log in to answer this question.