JH Labs Quantize Usage to reduce image color depth
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:
Quantized img:
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
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.
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.
精彩评论