0

我收到需要作为未压缩 TIFF 文件写入其他地方的大型 CCITT Group 4 压缩 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 的方法,但我不知道如何做到这一点。有人有建议吗?

4

3 回答 3

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 的了解太有限,帮不上什么忙。

于 2013-03-18T16:44:53.127 回答
1

我遇到了一些问题,最终结果可能会让您感到惊讶:

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

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

于 2012-06-01T09:46:39.507 回答
0

为您的 Java VM 提供更多内存。

如果这不起作用,请查看JAI 源代码中的 TIFF 插件的源代码。您也许可以编写自己的处理器,它只是使用流式方法解压缩数据结构(因此您永远不必随时将整个图像保存在内存中)。

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

于 2012-06-01T11:50:21.363 回答