Domanda

Una domanda che ho legge in immagini abbastanza grande (JPEG), ma ha solo bisogno di lavorare con le immagini più piccole in modo da li ho sotto-campione con qualcosa di simile

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

Tuttavia, a causa di un bug nel lettore jpeg che non gestisce alcuni meta-dati che devo ripiegare ad altri metodi, uno sta usando JAI per leggere l'immagine e quindi ridimensionare (codice è al di sotto, non devo usare riflessione come alcuni ambienti di distribuzione non hanno JAI a disposizione, so che potrei progettare intorno a questo meglio, ma è così che è).

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

Tuttavia alcune delle immagini sono molto grandi un tanto esco di eccezioni di memoria, c'è comunque posso ottenere JAI al sottocampionare l'immagine quando si legge nel modo ho letto le immagini utilizzando un ImageReader?

È stato utile?

Soluzione

Sto assumendo il fuori eccezione di memoria viene generata quando si tenta di fare la conversione a un BufferedImage?

Se questo è il caso, allora forse considerando attaccarsi alla RenderedOp che viene restituito dalla GAI di creare metodo e invece utilizzare un ParameterBlock e un ulteriore JAI creare per produrre l'immagine scalata?

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

Il codice di cui sopra è completamente testato di serie ho paura, ma dovrebbe iniziare!

Una volta che hai che ridimensionata RenderedOp si dovrebbe essere in grado di convertire in modo sicuro in un BufferedImage se si deve.

Altri suggerimenti

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();   
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top