无需通过BufferedImage即可解压缩TIFF文件

时间:2012-06-01 09:39:21

标签: java tiff jai javax.imageio

我收到大尺寸的CCITT Group 4压缩TIFF文件,需要在其他地方写为未压缩的TIFF文件。我正在使用jai_imageio TIFF阅读器和编写器来做这件事,只要图像的产品_width * height_适合整数,它就可以正常工作。

以下是我正在使用的代码:

TIFFImageReaderSpi readerSpi= new TIFFImageReaderSpi();
ImageReader imageReader = readerSpi.createReaderInstance();
byte[] data = blobManager.getObjectForIdAndVersion(id, version);
ImageInputStream imageInputStream = ImageIO.createImageInputStream(data); 
imageReader.setInput(imageInputStream);

TIFFImageWriterSpi writerSpi = new TIFFImageWriterSpi();
ImageWriter imageWriter = writerSpi.createWriterInstance();
ImageWriteParam imageWriteParam = imageWriter.getDefaultWriteParam();
imageWriteParam.setCompressionMode(ImageWriteParam.MODE_DISABLED);
//bufferFile is created in the constructor
ImageOutputStream imageOutputStream = ImageIO.createImageOutputStream(bufferFile);
imageWriter.setOutput(imageOutputStream);

//Now read the bitmap
BufferedImage bufferedImage = imageReader.read(0);
IIOImage iIOImage = new IIOImage(bufferedImage, null, null);
//and write it
imageWriter.write(null, iIOImage, imageWriteParam);

不幸的是,我收到的文件通常非常大,无法创建BufferedImage。 我一直试图找到一种从ImageReader直接流到ImageWriter的方法,但我无法找到如何做到这一点。 有人提出建议吗?

3 个答案:

答案 0 :(得分:1)

我遇到了一些问题,最终结果可能让你大吃一惊:

我最终使用Runtime.exec()方法使用一些命令行选项调用IrfanView。这样,我不担心压缩或大小,它只是工作,并为我输出正确的文件夹中的正确文件。

如果你在Linux上,你可以使用ImageMagik或类似的东西。

答案 1 :(得分:1)

您可以使用TIFF切片将TIFF分割成较小的部分(“瓷砖”)。如果您控制创建大图像的代码,JAI允许您逐个图块检索图像内容。

以下是如何使用JAI创建平铺图像的示例:

ColorModel cm = source.createColorModel();
// SampleModel with the tilesize
SampleModel sm = cm.createCompatibleSampleModel(tileWidth, tileHeight);
TiledImage image = new TiledImage(0, 0, imageWidth, imageHeight, 0, 0, sm, cm);

TIFFEncodeParam tep = new TIFFEncodeParam();
tep.setTileSize(tileWidth, tileHeight); // Set tile size to avoid OOM
tep.setWriteTiled(true);
JAI.create("filestore", image, filepath, "TIFF", tep);

如果你无法控制TIFF的制作,我对JAI的了解太有限了,无法提供太多帮助。

答案 2 :(得分:0)

为Java VM提供更多内存。

如果不起作用,请查看source code of the TIFF plugin in the JAI source code。您可以编写自己的处理器,它只使用流方法解压缩数据结构(因此您无需在任何时候将整个映像保留在内存中)。

如果这也不起作用,请查看JNA,它允许您从Java调用DLL中的代码(不需要C代码;一切都是从纯Java完成的,与Sun的JNI API不同)。 / p>