Search code examples
javaimagepngdecodeencode

How count colors from png files without full decoding?


Consider following java code:

File file = ...

BufferedImage image = ImageIO.read(file);
int w = image.getWidth();
int h = image.getHeight();
int count = 0;
for (int y = 0; y < h; y++) {
    for (int x = 0; x < w; x++) {
        int pixel = image.getRGB(x, y);
        //count colors here
    }
}

Here what is happened in the code above:

  1. Png bytes are from disk
  2. Bytes decoded with png decoder
  3. java image is constrcuted
  4. Colors is counted

Can I skip step 3? e.g. count bytes during decoding or better decode png image partially and store only color information. How to do that with java?

Note

As I spot, storing image with same dimention but different colors count leads to different size. For example photo can be 1000 bigger then same image but with one color (black for example). So theoretically it is possible to count image just read bytes without decode full image. Am I right? Or encoding algorithm do not support partially decoding?


Solution

  • If you want to avoid the creation of the full image, you could use PNGJ, a Java decoder library (disclaimer, my own) that allows to read the image progressively, row by row.

    The main advantage would be less memory consumption (only relevant if the image is big), perhaps also speed. A further difference with respect to a higher level iamge abstraction as BufferedImage is that the library gives you the raw pixel values in the format used by the PNG, without mappings or transformations - depending on your scenario, this can be a plus or not.

    Of course, you are still fully decoding the image, but there is no way of escaping this.