I have a tiff file of 18000 * 18000 in dimension and 1.20 GB . tiff has 72 DPI.
I want to convert this TIFF to PNG / JPEG using 400 DPI.
I am using the following code for this
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; }
the above code works fine for smaller images, then the specified image, for example, a tiff image of less than 5000 * 5000 in Dimension, can easily be converted to JPEG / PNG [although I need to change the PNG encoder],
but when I try to run the same code for the above file, it throws the following exception
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
this is due to a memory error.
whether it is available using Tiled Image Writer or Fragement Image Writer, we just convert a part of the image at a time, so we can work with ordinary memory, I think it could be called conversion using image segmentation.
EDIT
Directly write a png file using pngJ.
My goal is to transcode SVG canvas to PNG with 400 DPI
if I use PNGTranscoder for throwing an exception in memory for the specified image size.
so I used TiledImageTranscoder , which uses the following code to transcode SVG into an image.
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(); } }
, as you can see here, the above code finally uses TIFFImageEncoder to write to disk gradually and generates 1.30 GB of TIFF file in my case.
so I need to convert this generated file to a PNG file.
My question is here specifically for @leonbloy
you can use PNGWriter from the pngJ library here to directly write the png file using 400 DPI without memory errors, thereby we can also save time and avoid unnecessary conversion.
or
can we override the PngImageWriter writeImage method with the pngJ library so that we can achieve our goal?
Thanks Mihir Pareh