JH Labs Quantize Usage para reduzir a profundidade da cor da imagem
-
15-11-2019 - |
Pergunta
Estou tentando usar o QuantizeFilter em
http://www.jhlabs.com/ip/filters/index.html
para reduzir a profundidade de cor de uma captura de tela.
Aqui está meu código muito simples:
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 );
No entanto, o que me resta é:
Imagem original:
Imagem quantizada:
Uma análise mais aprofundada do problema mostra que o array inPixels está preenchido incorretamente;ele é preenchido três vezes com o terço superior da imagem original.
Alguma dica de como posso consertar isso?
Além disso, algum link de algoritmo de quantização bom + rápido em Java?O que procuro é um algoritmo que pegue uma imagem TYPE_INT_BGR e produza uma nova imagem TYPE_INT_BGR, mas com menos diferença real em pixels, para que possa ser facilmente esvaziada.
Por exemplo, se tivermos dois pixels na imagem original, com valores como 255, 255, 234 e outro com valor como 255, 255, 236, ambos deverão ser convertidos para 255.255.240.Saúde
Solução
O exemplo a seguir converterá sua imagem corretamente:
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);
Além disso, não há razão para criar os arquivos implicitamente, pois ImageIO.write os cria automaticamente.
Outras dicas
Eu tive o mesmo problema e não é o código que você postou que é o culpado, é o QuantizeFilter
classe que não passa por todos os pixels.Você precisa encontrar esta parte do código
if (!dither) {
for (int i = 0; i < count; i++)
outPixels[i] = table[quantizer.getIndexForColor(inPixels[i])];
e multiplique a contagem por 3.
Observe que isso só será uma correção se os dois últimos parâmetros forem definidos como falsos.