As Zek's answer points out, PNGJ is different from BufferedImage
: it's more low level, in that it does not try to represent the image pixels in an abstract general format (independent of the concrete PNG format), but instead gives you the values in format that maps directly to the PNG format and color model.
This means that, for example, if the PNG image is RGB you'll get the three RGB components as succesive (integer) values. If the PNG image is indexed, you'll get the index (integer value that points to a palette). If the PNG image is gray scale, you'll get the gray value as a single integer. Etc.
If you want to treat the pixel values in a more general way (give me the RGB values, no matter the underlying color model), you can do the conversion yourself, or take advantage of the helper methods in ImageLineHelper
class. Specifically, look at the methods convert2rgba()
and getPixelARGB8()
.
Bear in mind, though, that this class is merely a bunch of helper methods, that might be useful for you - or not. It's difficult to have a completely general conversion to RGB, because there are many complications and heuristics - PNG allows several transparency modes, depths, color spaces... (what if the image is 2bits depth? what if it's 16 bits? what if it has a non-standard color profile or gamma correction, or it has a single transparency chunk, or... etc)? If you want to support the full set of PNG images, it's almost required to understand the underlying format and the complications.
(But, but... BufferedImage
does that, with total generality, without ambiguities and without problems, you say? not exactly)
If you are OK with restricting to your colour model (RGB, 8 bits, no alpha) (and you have no transparency TRNS chunk or gamma peculiarities, or don't care) then it's quite simple:
for (int i = 0,j=0 ; i < reader.imgInfo.cols; i++, j+=channels ) {
int r = scanLine[j];
int g = scanLine[j+1];
int b = scanLine[j+2];
// ...
}
Disclaimer: I'm the PNGJ coder.