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

时间:2017-06-15 11:06:10

标签: java tiff jai

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

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

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容器页面输入流?提前谢谢。

1 个答案:

答案 0 :(得分:3)

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

通过使用com.twelvemonkeys.contrib.tiff中的TIFFUtilities类,您应该能够将多页TIFF拆分为多个单页TIFF,如下所示:

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

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

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