Search code examples
javagraphicscolorsjava-2dquantization

Color quantization diluting pure whites


I have a simple quantization function

public static int quantize(int oldpixel) {

    int r = (oldpixel >> 16) & 0xff;
    int g = (oldpixel >> 8) & 0xff;
    int b = (oldpixel >> 0) & 0xff;

    int color = 0xff << 24 | (((int) ((r) / 32) * 32) & 0xff) << 16 | 
            (((int) ((g) / 32) * 32) & 0xff) << 8 | 
            (((int) ((b) / 32) * 32)& 0xff) << 0;
    return color;
}

What it does is reduce a color to a lower detail color, then expands it, this artificially limits the pallet and I'll use it for a dither filter, an image through the function produces this

In: Unquantized hue wheel Out: Quantized hue wheel

This is almost perfect as the result, except the whites are reduced to a gray, I understand the cause is my flooring of divided colors in the algorithm, but I do not know how to fix this, any suggestions would be appreciated

enter image description here

enter image description here


Solution

  • After dividing each component by 32, you have an integer between 0 and 7. You are trying to map this back to the range 0 to 255, so that 0 is 0 and 7 is 255.

    You can do this by multiplying it by 255/7, which happens to be about 36.428.

    You could use something like (int)((r / 32) * (255.0 / 7.0)), but the cast is ugly in Java. To improve that you could wrap it in a function, and have quantizeChannel(r), quantizeChannel(g) and quantizeChannel(b). Or you could swap the order and use integer arithmetic: r / 32 * 255 / 7.