itextsharp:拆分页面大小等于文件大小

这是我如何拆分大pdf(144 MB)

public int SplitAndSave(string inputPath, string outputPath) { FileInfo file = new FileInfo(inputPath); string name = file.Name.Substring(0, file.Name.LastIndexOf(".")); using (PdfReader reader = new PdfReader(inputPath)) { for (int pagenumber = 1; pagenumber <= reader.NumberOfPages; pagenumber++) { string filename = pagenumber.ToString() + ".pdf"; Document document = new Document(); PdfCopy copy = new PdfCopy(document, new FileStream(outputPath + "\\" + filename, FileMode.Create)); document.Open(); copy.AddPage(copy.GetImportedPage(reader, pagenumber)); document.Close(); } return reader.NumberOfPages; } } 

对于大多数pdfs(小尺寸,我猜旧格式)一切正常。 但对于大的(可能使用像refstreams这样的东西……以获得最佳压缩),spliited页面打开为一页,但其大小等于pdf大小。 我能做什么?

如果您的文档Top_Gear_Magazine_2012_09.pdf确实是我提到的原因:所有页面都将对象2 0 R称为其资源 ,而2 0 obj中的字典依次引用PDF中的所有图像。

要将该文档拆分为仅包含所需图像的部分文档,您应首先找出哪些图像属于哪些页面然后为所有页面创建个人/资源词典来预处理文档。

由于您已在此上下文中使用iText,因此您还可以使用它来查找哪些页面所需的图像。 使用iText parser包最初使用RenderListener实现逐页解析PDF, RenderImage方法只记住当前页面上使用的图像对象。 (作为一种特殊的转折,iText隐藏了所讨论的图像XObject的名称;但是,您可以获得间接对象,并且可以查询其对象和世代号,这足以满足下一步的需要。)

在第二步中,您将在PdfStamper打开文档并遍历页面。 对于每个页面,您检索/ Resources字典并将其复制,但仅复制那些引用其中一个图像对象的XObjects引用,这些图像对象的对象编号和生成是您在第一步中记住的相应页面。 最后,将缩小的副本设置为相关页面的/ Resources字典。

生成的PDF应该分割得很好。

PS最近在iText邮件列表上出现了一个非常类似的问题。 在该线程中,此处给出的解决方案配方已得到改进 ,为了解决iText隐藏xobject名称所带来的困难,我现在建议在使用不同的ContentOperator for“Do”之前进行干预,这里是Java版本:

 class Do implements ContentOperator { public void invoke(PdfContentStreamProcessor processor, PdfLiteral operator, ArrayList operands) throws IOException { PdfName xobjectName = (PdfName)operands.get(0); names.add(xobjectName); } final List names = new ArrayList(); } 

此内容运算符只是收集使用的xobjects的名称,即为给定页面保留的xobject资源。