Java 解压缩TIFF文件而不经过BuffereImage

Java 解压缩TIFF文件而不经过BuffereImage,java,tiff,jai,javax.imageio,Java,Tiff,Jai,Javax.imageio,我收到了大尺寸CCITT Group 4压缩TIFF文件,需要作为未压缩TIFF文件写入其他地方。我正在使用jai_imageio TIFF读写器来实现这一点,只要图像的乘积_width*height_与整数匹配,它就可以正常工作 以下是我正在使用的代码: TIFFImageReaderSpi readerSpi= new TIFFImageReaderSpi(); ImageReader imageReader = readerSpi.createReaderInstance(); byte[

我收到了大尺寸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);
不幸的是,我收到的文件通常非常大,无法创建BuffereImage。 我一直在试图找到一种从ImageReader直接流到ImageWriter的方法,但我不知道如何做到这一点。
有人提出建议吗?

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

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


如果您在Linux上,可以使用ImageMagik或类似的工具。

为Java虚拟机提供更多内存

如果这不起作用,看看下面的例子。您可能可以编写自己的处理器,使用流式方法解压数据结构(这样您就不必在任何时候将整个图像保存在内存中)


如果这也不起作用,那么看看哪个允许您从Java调用DLL中的代码(不需要C代码;与Sun的JNI API不同,一切都是从纯Java完成的)。

您可以使用TIFF tiles将TIFF分割成更小的部分(“tiles”)。如果您控制创建大图像的代码,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的了解太有限,无法提供太多帮助。

谢谢,但这不是我的选择。首先,因为它不是开源的,只在Windows下运行。如果我决定使用本机代码,我可以很容易地使用libtiff编写自己的解压器。你可以在Linux上使用ImageMagik做同样的事情:)我的问题是关于JAI类的。我知道Java环境之外还有其他解决方案,但这不是我想要的。一旦数组超出整数范围,您就会遇到麻烦。也许有办法对映像进行分区?谢谢,但这与VM内存无关。问题是图像数据数组的增长大于整数的最大值。我确实可以使用JAI代码,但这是我想要避免的。JNA听起来是一个有趣的项目,但JNI在其他地方对我来说效果很好。我只是想避免从外部解决这个问题,但从表面上看,这似乎是不可能的。