JH Labs Quantize Usage to reduce image color depth

2.3k views Asked by At

I am trying to use the QuantizeFilter in

http://www.jhlabs.com/ip/filters/index.html

to reduce the color depth of a screen shot.

Here is my very very simple code:

    Robot robo = new Robot();
    BufferedImage notQuantized = robo.createScreenCapture( new Rectangle ( 0, 0, 300, 300 ) );
    BufferedImage Quantized = new BufferedImage( 300, 300, BufferedImage.TYPE_INT_BGR);
    File nonquantized = new File ("C:\\nonquantized.png");
    File quantized = new File("C:\\quantized.png");
    nonquantized.createNewFile();
    quantized.createNewFile();
    QuantizeFilter bla = new QuantizeFilter();

    int [] outPixels = new int[300*300*3];
    int [] inPixels = new int[300*300*3];

    notQuantized.getRaster().getPixels( 0, 0, 300, 300, inPixels );
    bla.quantize( inPixels, outPixels, 300, 300,2, true, true );

    Quantized.getRaster().setPixels( 0, 0, 300, 300, outPixels );
    ImageIO.write( Quantized, "png", quantized );
    ImageIO.write( notQuantized, "png", nonquantized );

However, what I am left with is:

Original img:

enter image description here

Quantized img:

enter image description here

A further analysis of the problem shows that the inPixels array is filled incorrectly; it is filled three times with the upper one-third of the original image.

Any pointers how I can fix that?

Additionally, any links good + fast quantization algorithm in Java? What I search for is an algorithm that will take a TYPE_INT_BGR image and produce a new TYPE_INT_BGR image but with less actual difference in pixels, so it could be easily deflated.

For example, if we have two pixels in the original image, with values like 255, 255, 234 and another one with value like 255, 255, 236, they should both be converted to 255,255,240. Cheers

2

There are 2 answers

0
JR Lomas On BEST ANSWER

The following example will convert your image correctly:

QuantizeFilter q = new QuantizeFilter();
int [] inPixels = new int[image.getWidth()*image.getHeight()*3];
int [] outPixels = new int[image.getWidth()*image.getHeight()*3];
image.getRaster().getPixels( 0, 0, image.getWidth(), image.getHeight(), inPixels );
q.quantize(inPixels, outPixels, image.getWidth(), image.getHeight(), 64, false, false);
WritableRaster raster = (WritableRaster) image.getData();
raster.setPixels(0,0,width,height,outPixels);

Also there is no reason to create the files implicitly, as ImageIO.write creates them automatically.

0
Victor On

I have had the same problem and its not the code you posted that's at fault it's the QuantizeFilter class which doesn't go through all the pixels. You need to find this code part

 if (!dither) {
        for (int i = 0; i < count; i++)
            outPixels[i] = table[quantizer.getIndexForColor(inPixels[i])];

and multiply count by 3.

Please note that this is only a a fix if the last 2 parameters are set to false.