Ho un file tiff 18000 * 18000 in Dimensione e dimensioni 1,20 GB. il tiff ha 72 DPI.Come posso convertire un'enorme immagine TIFF in PNG/JPEG senza errori di memoria esauriti?
Voglio convertire questo TIFF in PNG/JPEG usando 400 DPI.
Sto usando seguente codice per farlo
public static void ConvertTiffToJpg(String str_TiffUrl,
String str_JpgFileDestinationUrl) throws Exception {
try {
FileSeekableStream obj_FileSeekableStream = new FileSeekableStream(
new File(str_TiffUrl));
ImageDecoder obj_ImageDecoder = ImageCodec.createImageDecoder(
"tiff", obj_FileSeekableStream, null);
RenderedImage obj_RenderedImage = obj_ImageDecoder
.decodeAsRenderedImage();
JAI.create("filestore", obj_RenderedImage,
str_JpgFileDestinationUrl, "jpeg");
obj_RenderedImage = null;
obj_ImageDecoder = null;
obj_FileSeekableStream.close();
} catch (Exception ex) {
throw ex;
}
il codice precedente funziona perfettamente per le immagini più piccole, allora l'immagine specificata immagine esempio tiff meno di 5000 * 5000 in Dimension può essere facilmente convertito in JPEG/PNG per [anche se ho bisogno di cambiare l'encoder PNG],
ma quando si tenta di eseguire lo stesso codice per il file di cui sopra viene generata seguente eccezione
Error: One factory fails for the operation "encode"
Occurs in: javax.media.jai.ThreadSafeOperationRegistry
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at javax.media.jai.FactoryCache.invoke(FactoryCache.java:122)
at javax.media.jai.OperationRegistry.invokeFactory(OperationRegistry.java:1674)
at javax.media.jai.ThreadSafeOperationRegistry.invokeFactory(ThreadSafeOperationRegistry.java:473)
at javax.media.jai.registry.RIFRegistry.create(RIFRegistry.java:332)
at com.sun.media.jai.opimage.FileStoreRIF.create(FileStoreRIF.java:138)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at javax.media.jai.FactoryCache.invoke(FactoryCache.java:122)
at javax.media.jai.OperationRegistry.invokeFactory(OperationRegistry.java:1674)
at javax.media.jai.ThreadSafeOperationRegistry.invokeFactory(ThreadSafeOperationRegistry.java:473)
at javax.media.jai.registry.RIFRegistry.create(RIFRegistry.java:332)
at javax.media.jai.RenderedOp.createInstance(RenderedOp.java:819)
at javax.media.jai.RenderedOp.createRendering(RenderedOp.java:867)
at javax.media.jai.RenderedOp.getRendering(RenderedOp.java:888)
at javax.media.jai.JAI.createNS(JAI.java:1099)
at javax.media.jai.JAI.create(JAI.java:973)
at javax.media.jai.JAI.create(JAI.java:1621)
at com.vs.graphics.concepts.TiffToJpeg.ConvertTiffToJpg(TiffToJpeg.java:30)
at com.vs.graphics.svg.SvgRefresh$1.actionPerformed(SvgRefresh.java:106)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1995)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2318)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:236)
at java.awt.Component.processMouseEvent(Component.java:6216)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3265)
at java.awt.Component.processEvent(Component.java:5981)
at java.awt.Container.processEvent(Container.java:2041)
at java.awt.Component.dispatchEventImpl(Component.java:4583)
at java.awt.Container.dispatchEventImpl(Container.java:2099)
at java.awt.Component.dispatchEvent(Component.java:4413)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4556)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4220)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4150)
at java.awt.Container.dispatchEventImpl(Container.java:2085)
at java.awt.Window.dispatchEventImpl(Window.java:2475)
at java.awt.Component.dispatchEvent(Component.java:4413)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
Caused by: java.lang.OutOfMemoryError: Java heap space
at java.awt.image.DataBufferByte.<init>(DataBufferByte.java:42)
at java.awt.image.Raster.createInterleavedRaster(Raster.java:253)
at java.awt.image.Raster.createInterleavedRaster(Raster.java:194)
at com.sun.media.jai.codecimpl.JPEGImageEncoder.encode(JPEGImageEncoder.java:182)
at com.sun.media.jai.opimage.EncodeRIF.create(EncodeRIF.java:70)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at javax.media.jai.FactoryCache.invoke(FactoryCache.java:122)
at javax.media.jai.OperationRegistry.invokeFactory(OperationRegistry.java:1674)
at javax.media.jai.ThreadSafeOperationRegistry.invokeFactory(ThreadSafeOperationRegistry.java:473)
at javax.media.jai.registry.RIFRegistry.create(RIFRegistry.java:332)
at com.sun.media.jai.opimage.FileStoreRIF.create(FileStoreRIF.java:138)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at javax.media.jai.FactoryCache.invoke(FactoryCache.java:122)
at javax.media.jai.OperationRegistry.invokeFactory(OperationRegistry.java:1674)
at javax.media.jai.ThreadSafeOperationRegistry.invokeFactory(ThreadSafeOperationRegistry.java:473)
at javax.media.jai.registry.RIFRegistry.create(RIFRegistry.java:332)
at javax.media.jai.RenderedOp.createInstance(RenderedOp.java:819)
at javax.media.jai.RenderedOp.createRendering(RenderedOp.java:867)
at javax.media.jai.RenderedOp.getRendering(RenderedOp.java:888)
at javax.media.jai.JAI.createNS(JAI.java:1099)
at javax.media.jai.JAI.create(JAI.java:973)
at javax.media.jai.JAI.create(JAI.java:1621)
at com.vs.graphics.concepts.TiffToJpeg.ConvertTiffToJpg(TiffToJpeg.java:30)
at com.vs.graphics.svg.SvgRefresh$1.actionPerformed(SvgRefresh.java:106)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1995)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2318)
Error: One factory fails for the operation "filestore"
Occurs in: javax.media.jai.ThreadSafeOperationRegistry
questo a causa dell'errore di memoria insufficiente.
c'è qualche piastrella Image Writer o Fragement Image Writer disponibile ad usarlo ci limiteremo a convertire una porzione di un'immagine alla volta, così possiamo lavorare con la memoria normale disponibili penso che potrebbe essere chiamato convertito utilizzando la segmentazione di immagini .
EDIT
scrivere direttamente file PNG utilizzando pngJ.
Il mio scopo è quello di transcodifica tela SVG in PNG con 400 DPI
se io uso PNGTranscoder per ciò che getta un'eccezione di memoria per dimensioni dell'immagine menzionato.
così ho usato TiledImageTranscoder che usa il seguente codice per transcodificare SVG in Immagine.
protected void transcode(Document document, String uri,
TranscoderOutput output) throws TranscoderException {
// Sets up root, curTxf & curAoi
super.transcode(document, uri, output);
Filter f = this.root.getGraphicsNodeRable(true);
RenderContext rc = new RenderContext(curTxf, null, null);
RenderedImage img = f.createRendering(rc);
// prepare the image to be painted
int w = img.getWidth();
int h = img.getHeight();
try {
int bands = img.getSampleModel().getNumBands();
int[] off = new int[bands];
for (int i = 0; i < bands; i++)
off[i] = i;
SampleModel sm = new PixelInterleavedSampleModel(
DataBuffer.TYPE_BYTE, w, (100000 + w - 1)/w, bands, w
* bands, off);
RenderedImage rimg = new FormatRed(GraphicsUtil.wrap(img), sm);
TIFFImageEncoder enc = new TIFFImageEncoder(output
.getOutputStream(), null);
enc.encode(rimg);
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
così come si può vedere qui il codice sopra usa finalmente TIFFImageEncoder scrivere progressivamente su disco e genera 1,30 GB di file TIFF nel mio caso.
ecco perché ho bisogno di convertire questo file generato in file PNG.
la mia domanda qui è specialmente per @leonbloy
possiamo usare qui PNGWriter dalla libreria pngJ di scrivere direttamente il file PNG con 400 DPI senza errore di memoria, in questo modo siamo in grado di risparmiare tempo come bene e evitare conversioni inutili.
o
possiamo override metodo writeImage PngImageWriter s' con biblioteca pngJ così possiamo raggiungere il nostro obiettivo?
Thank You Mihir Parekh
Hai provato il parametro VM '-Xmx'? Qualcosa come '-Xmx3G' per consentire un utilizzo massimo della memoria di 3 gigabyte. – jlordo
@jlordo per favore non suggerirmi questo parametro voglio eseguire questo codice usando solo 64 - 512 mb di memoria heap.seguimi segmentazione dell'immagine – Mihir
Abbiamo un problema simile. Tuttavia usiamo uno strumento nativo per gestirlo. Richiama il comando tiff2png e lascia che il SO gestisca il problema di memoria. Vedi http://www.libpng.org/pub/png/apps/tiff2png.html. Strumenti disponibili su macchine Linux per impostazione predefinita. – nobody