我正在尝试使用Java中的itextpdf库将现有的pdf文件复制到一些新文件中。我使用的是版本5.5.10的itextpdf。我在两个方面面临着不同的问题:PDFStamper和PdfCopy。当我使用PDFStamper类时,我发现虽然没有添加任何新项目,但新文件大小增加了很多。这是代码片段:
String currFile="C:\misc\pdffiles\AcroJS.pdf" ;
String dest = "C:\misc\pdffiles\AcroJS_copy.pdf" ;
PdfReader reader = new PdfReader(currFile) ;
PdfStamper stamper = new PdfStamper(reader,new FileOutputStream(dest)) ;
stamper.close() ;
reader.close() ;
一些观察结果是:7 MB(原始)到13 MB(大约,新文件),116 KB> 119 KB(约)
在复制现有的pdf文件时,我期待大致相同的文件大小。我无法弄清楚为什么尺寸会增加那么多。
我也尝试过PdfCopy类。我用PdfCopy跟踪了两种方法:
但这两种方法的问题在于它从pdf文件中丢弃了一些非内容元数据,因此当Adobe Reader打开时,新的pdf正在破坏。例如,我的pdf包含字典对象PdfName.S。在这种情况下,新创建的pdf文件只有2KB(原始版本为1.6 MB),它显然意味着没有任何内容被复制到文档中并且它已被破坏。
我原来的要求很简单:将现有的pdf复制到新的pdf文件,不增加大小,不丢弃必要的项目。显而易见它不像,复制,粘贴然后重命名。因为在下一步中,我有一些与pdf内容有关的处理。任何帮助都感激不尽。
操作系统:Windows 10专业版 Java:1.8.101 itext:5.5.10
感谢
答案 0 :(得分:3)
PdfStamper
您的代码
PdfStamper stamper = new PdfStamper(reader,new FileOutputStream(dest)) ;
stamper.close() ;
基本上告诉iText复制原始PDF 丢弃未使用的对象并使用iText的默认压缩设置。
iText的默认压缩设置包括不使用压缩的交叉引用和对象流(在PDF 1.5中引入),但旧的交叉引用表技术和单独压缩的对象。
另一方面,示例文件确实使用了这些技术。因此,压缩得更好。
您也可以告诉iText使用这些改进的压缩技术,如下所示:
PdfReader reader = new PdfReader(resourceStream);
PdfStamper stamper = new PdfStamper(reader, outputStream);
stamper.setFullCompression();
stamper.close();
(Stamping.java测试方法testStampAcroJSCompressed
)
这会导致文件大小小于4 MB。
如果您希望忠实于存储对象的原始方式,您可以使用附加模式,该模式以相同方式复制原始文件,并以所谓的增量更新的形式添加更改,如下所示:
PdfReader reader = new PdfReader(resourceStream);
PdfStamper stamper = new PdfStamper(reader, outputStream, '\0', true);
stamper.close();
(Stamping.java测试方法testStampAcroJSAppended
)
这会导致文件略大于原始文件。
PdfCopy
您发现了PdfCopy
正在丢弃一些非内容元数据
当然可以。 PdfCopy
旨在将页从一个PDF复制到另一个PDF,保留内容和注释,但忽略其他页级和所有文档级信息。