C# itextsharp 5 writer.DirectContent创建的文件比PDFStamper小50%

C# itextsharp 5 writer.DirectContent创建的文件比PDFStamper小50%,c#,itext,pdfstamper,C#,Itext,Pdfstamper,我真的很想使用更新的方法使用PDFStamper,而不是使用旧的方法PdfWriter.GetInstance。。。但是使用旧方法创建的PDF文件大小是使用新方法创建的PDF文件大小的1/2。这两种方法之间有什么我遗漏的吗 //Old way using PdfWriter.GetInstance... writer.DirectContent public static void AddHeaderTextLayer() { string

我真的很想使用更新的方法使用PDFStamper,而不是使用旧的方法PdfWriter.GetInstance。。。但是使用旧方法创建的PDF文件大小是使用新方法创建的PDF文件大小的1/2。这两种方法之间有什么我遗漏的吗

//Old way using PdfWriter.GetInstance... writer.DirectContent
        public static void AddHeaderTextLayer()
        {
            string HdrLeft = string.Empty;
            string HdrRight = string.Empty;
            string PageHdrName = "XHdr";
            string NoOfPagesPadded = string.Empty;
            string PageNoPadded = string.Empty;
            int xLeft = 30;
            int xRight = 100;
            int xTop = 15;
            string filename = "4_20140909.pdf";

            PdfReader reader = new PdfReader(@"C:\!stuff\Junk\ChemWatchPDF\" + filename); // input file

            using (var fileStream = new FileStream(@"C:\!stuff\Junk\ChemWatchPDF\" + filename.Replace(".pdf", "") + "_withHdrLTp.pdf", FileMode.Create, FileAccess.Write))
            {
                var document = new Document(reader.GetPageSizeWithRotation(1));
                var writer = PdfWriter.GetInstance(document, fileStream);
                document.Open();

                for (var i = 1; i <= reader.NumberOfPages; i++)
                {
                    Rectangle pageRect = reader.GetPageSize(i);
                    document.NewPage();

                    var baseFont = BaseFont.CreateFont(BaseFont.HELVETICA_BOLD, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
                    var importedPage = writer.GetImportedPage(reader, i);
                    var contentByte = writer.DirectContent;

                    contentByte.AddTemplate(importedPage, 0, 0);
                    string SDSNo = "12345678";
                    HdrLeft = $"Company MSDS# {SDSNo}";

                    NoOfPagesPadded = (reader.NumberOfPages.ToString());
                    PageNoPadded = i.ToString();
                    HdrRight = $" Page {PageNoPadded} of {NoOfPagesPadded}";

                    contentByte.BeginLayer(new PdfLayer(PageHdrName + i.ToString(), writer));

                    contentByte.BeginText();
                    contentByte.SetFontAndSize(baseFont, 10);
                    contentByte.SetColorFill(LabColor.RED);
                    contentByte.ShowTextAligned(PdfContentByte.ALIGN_LEFT, HdrLeft, pageRect.Left + xLeft, pageRect.Top - xTop, 0);
                    contentByte.EndText();

                    contentByte.BeginText();
                    contentByte.SetFontAndSize(baseFont, 10);
                    contentByte.SetColorFill(LabColor.RED);
                    contentByte.ShowTextAligned(PdfContentByte.ALIGN_LEFT, HdrRight, pageRect.Right - xRight, pageRect.Top - xTop, 0);
                    contentByte.EndText();

                    contentByte.EndLayer();
                }
                document.Close();
                writer.Close();
            }
        }


新方法的输出包含一个结构树,我假设它来自原始文档。它在旧方法的输出中丢失了

结构树描述文档的逻辑结构。它增加了文档的可访问性,在越来越多的国家和环境中,文档的存在成为法律要求。因此,丢弃结构树通常是一个坏主意

结构树本身由许多小的间接对象组成,对于PDF,总共有1000多个间接对象,大小约为90KB。此外,每个间接对象都需要一个20字节的交叉引用条目,在您的示例中,该条目的总大小接近20KB。这几乎解释了两个输出之间111KB大小的所有差异

如果使用对象流和交叉引用流,结构树通常可以得到相当好的压缩。因此,我建议您在iText中激活完全压缩,使其使用对象流和交叉引用流:

PdfStamper pdfStamper = new PdfStamper(reader, newPDF);
pdfStamper.SetFullCompression();
pdfStamper.Writer.CompressionLevel = 9;
通过使用PdfReader/PdfStamper和这些设置简单地处理您的大型PDF文件,而无需任何其他操作,我将您的文件大小从234KB减少到133KB


顺便说一下,您使用PdfWriter调用该方法,页面导入使用旧方法,使用PdfStamper调用新方法。实际上,PdfStamper类至少从2003年起就存在于iText中!所以它不是真的旧与新…

通常不应该发生。。。除非源PDF中的内容比使用PdfWriter.GetImportedPage复制的内容多得多。例如,可能存在结构树或附件,或隐藏的页面模板,或XFA表单,或。因此,你能分享有问题的PDF进行分析吗?mkl-我会将PDF的电子邮件发送给你。谢谢
PdfStamper pdfStamper = new PdfStamper(reader, newPDF);
pdfStamper.SetFullCompression();
pdfStamper.Writer.CompressionLevel = 9;