JAI:如何从多页 TIFF 图像容器中提取单页输入流?

JAI: How do I extract a single page input stream from a multipaged TIFF image container?

我有一个组件可以将 PDF 文档转换为图像,每页一张图像。由于该组件使用转换器生成内存中的图像,它会严重占用 JVM 堆并需要一些时间才能完成转换。

我正在尝试提高转换过程的整体性能,并找到了一个带有 JNI 绑定的本机库来将 PDF 转换为 TIFF。该库只能将 PDF 转换为单个 TIFF 文件(需要中间文件系统存储;甚至不消耗转换流),因此结果 TIFF 文件已嵌入转换页面,而不是文件系统上的每页图像。拥有本机库可以显着提高整体转换速度,并且性能变得非常快,但是存在一个真正的瓶颈:因为我必须将源页面转换为目标页面,现在我必须从结果文件中提取每个页面并写入他们都在别处。使用 RenderedImages:

的简单而天真的方法
final SeekableStream seekableStream = new FileSeekableStream(tempFile);
final ImageDecoder imageDecoder = createImageDecoder("tiff", seekableStream, null);
...
//                                               V--- heap is wasted here
final RenderedImage renderedImage = imageDecoder.decodeAsRenderedImage(pageNumber);
// ... do the rest stuff ...

实际上,我真的很想从 TIFF 容器文件 (tempFile) 中提取一个具体的页面输入流,然后将其重定向到其他地方,而不必将其存储为内存中的图像.我会想象一种类似于容器处理的方法,我需要在其中寻找特定的条目以从中提取数据(比如 ZIP 文件处理等)。但是我在 ImageDecoder 中找不到类似的东西,或者我的期望可能有误,只是遗漏了一些重要的东西...

是否可以使用 JAI API 或第三方替代方案来提取 TIFF 容器页面输入流?提前致谢。

我可能是错的,但不要认为 JAI 支持在不将文件解码为内存图像的情况下拆分 TIFF。并且,很抱歉推广我自己的库,但我认为它确实可以满足您的需求(用于拆分 TIFF 的解决方案的主要部分由第三方提供)。

通过使用 com.twelvemonkeys.contrib.tiff 中的 TIFFUtilities class,您应该能够像这样将多页 TIFF 拆分为多个单页 TIFF:

TIFFUtilities.split(tempFile, new File("output"));

不对图像进行解码,仅将每个 IFD 拆分为一个单独的文件,并使用更正的偏移量和字节数写入流。

文件将被命名为output/0001.tifoutput/0002.tif等。如果您需要更好地控制输出名称或有其他要求,您可以轻松修改代码。该代码带有 BSD 风格的许可证。