Question

Une application je lit en images assez grandes (jpegs), mais n'a besoin que de travailler avec des images plus petites pour que je les sous-échantillon avec quelque chose comme

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

Toutefois, en raison d'un bogue dans le lecteur jpeg qui ne gère pas certaines données méta que j'ai revenir à d'autres méthodes, on utilise l'IMA pour lire l'image, puis redimensionner (le code est ci-dessous, pas que je dois utiliser la réflexion que certains environnements de déploiement ne pas disponible JAI, je sais que je pourrais concevoir autour de ce mieux mais c'est comme ça).

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) {
// ...
}

Toutefois, certaines des images sont très grandes d'un maintenant et encore une fois je sors des exceptions de mémoire, est-il de toute façon je peux obtenir jai sous-échantillonner l'image quand il est lu de la façon que je lis les images à l'aide d'un ImageReader?

Était-ce utile?

La solution

Je suppose l'exception de la mémoire est lancée lorsque vous essayez de faire la conversion en BufferedImage?

Si tel est le cas, alors peut-être envisager de coller à la RenderedOp qui est retourné par la méthode de créer et d'utiliser à la place JAI une ParameterBlock et un autre créer pour JAI produire l'image à l'échelle?

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);

Le code ci-dessus est entièrement non testé en standard j'ai peur, mais si vous commencer!

Une fois que vous avez que redimensionnée RenderedOp vous devriez être en mesure de convertir en toute sécurité à un BufferedImage si vous devez.

Autres conseils

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();   
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top