Pergunta

Um aplicativo eu tenho lê em imagens muito grandes (JPEGs), mas só precisa trabalhar com imagens menores para que eu subamostra-los com algo como

ImageReadParam param = reader.getDefaultReadParam();
param.setSourceSubsampling(4, 4, 0, 0);
img = reader.read(0);

No entanto, devido a um bug no leitor jpeg que não lidar com alguns dados de meta que eu cair de volta para outros métodos, a pessoa está usando JAI para ler a imagem e, em seguida, redimensionar (código está abaixo, não tenho de uso reflexão como alguns ambientes de implantação não tem JAI disponível, eu sei que eu poderia projetar em torno deste melhor, mas é assim que é).

try {
Class<?> c = ImageUtil.class.getClassLoader().loadClass("javax.media.jai.JAI");

if (c != null) { 
    URL url = new URL("file://" + file.getAbsolutePath());
    Method m = c.getMethod("create", String.class, Object.class);
    Object pi = m.invoke(null, "url", url);
    img = (BufferedImage) pi.getClass().getMethod("getAsBufferedImage").invoke(pi);
}
} catch (Throwable tt) {
// ...
}

No entanto algumas das imagens são muito grandes uma vez em quando eu sair da memória exceções, há de qualquer maneira eu posso obter JAI a subamostra a imagem quando ele é lido da maneira i ler as imagens usando um ImageReader?

Foi útil?

Solução

Estou assumindo o fora de exceção de memória é lançada quando você tentar fazer a conversão para um BufferedImage?

Se for esse o caso, então talvez considerando aderindo ao RenderedOp que é devolvido pelo JAI de criar método e passar a usar um ParameterBlock e mais JAI Criar para produzir a imagem dimensionada?

ParameterBlock paramBlock = new ParameterBlock();
paramBlock.addSource(((RenderedOp) pi).createInstance()); // Updated this
paramBlock.add(0.5f); // x Scale (Change these two Scale values!)
paramBlock.add(0.5f); // y Scale
paramBlock.add(0.0f); // x Translate
paramBlock.add(0.0f); // y Translate
paramBlock.add(new InterpolationBilinear()); // I think this Interpolation should work...)
RenderedOp resized = JAI.create("scale", paramBlock, null);

O código acima vem totalmente testado como padrão Eu tenho medo, mas deve começar!

Uma vez que você tem que RenderedOp redimensionada você deve ser capaz de segurança convertê-lo em um BufferedImage se você tiver que.

Outras dicas

RenderedOp rop = JAI.create("fileload", file.getAbsolutePath());

ParameterBlock pb = new ParameterBlock();
pb.addSource(rop);
pb.add(0.5f);
pb.add(0.5f);
rop = JAI.create("scale", pb);

// For better looking results, but slower:
// rop = JAI.create("SubsampleAverage", pb);

BufferedImage bufImg = rop.getAsBufferedImage();   
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top