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

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

我正在尝试提高转换过程的整体性能,并找到了一个带有JNI绑定的本机库,可以将PDF转换为TIFF。 该库只能将PDF转换为单个TIFF文件(需要中间文件系统存储;甚至不使用转换流),因此结果TIFF文件已嵌入转换页面,而不是文件系统上的每页图像。 拥有一个本地库可以极大地改善整体转换并且性能变得非常快,但是存在一个真正的瓶颈:因为我必须将源页面转换为目标页面转换,现在我必须从结果文件中提取每个页面并写入其他所有人。 一个简单而天真的RenderedImage方法:

 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找不到类似的ImageDecoder ,或者我可能错了我的期望,只是错过了一些重要的东西……

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

我可能是错的,但不要认为JAI支持拆分TIFF而不将文件解码为内存中的图像。 并且,抱歉推销我自己的库,但我认为它完全符合您的需求(用于拆分TIFF的解决方案的主要部分由第三方提供)。

通过使用TIFFUtilities类,您应该能够将多页TIFF拆分为多个单页TIFF,如下所示:

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

不对图像进行解码,仅将每个IFD分成单独的文件,并且使用校正的偏移和字节计数来写入流。

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