c# - 当我尝试压缩不同级别的 pdf 文件时,ITextSharp 返回相同大小的 pdf

标签 c# pdf compression itext

我正在阅读 pdf 并使用 itextsharp 注入(inject)一些内容。生成的 byte[] 与压缩级别一起传递给下面的方法。

public static byte[] method(byte[] pdf,int compressionlevel)
        {
            using (MemoryStream outputPdfStream1 = new MemoryStream())
            {
                //PdfReader reader1 = new PdfReader(pdf);
                //PdfStamper stamper1 = new PdfStamper(reader1, outputPdfStream1);
                //int level = (int)compressionlevel;
                //if (level <= 9)
                //    stamper1.Writer.CompressionLevel = (int)compressionlevel;
                //else
                //    stamper1.Writer.SetFullCompression();
                //stamper1.SetFullCompression();
                //stamper1.Close();
                //byte[] newfile = outputPdfStream1.ToArray();
                //return newfile;

                PdfReader reader = new PdfReader(pdf);
                PdfStamper stamper = new PdfStamper(reader, outputPdfStream1,PdfWriter.VERSION_1_5);
                int level = (int)compressionlevel;
                if (level <= 9)
                {
                   stamper.Writer.CompressionLevel = level;
                }
                else
                    stamper.Writer.SetFullCompression();
                int total = reader.NumberOfPages + 1;
                for (int i = 1; i < total; i++)
                {
                    reader.SetPageContent(i, reader.GetPageContent(i));
                }
                stamper.SetFullCompression();
                stamper.Close();
                byte[] newfile = outputPdfStream1.ToArray();
                return newfile;
            }
        } 

如果我评论 stamper.SetFullCompression(); 那么这个方法将返回相同大小的字节数组,而不考虑正在传递的压缩级别(在每种情况下从 0 传递到 9)..

如果我取消注释 stamper.SetFullCompression(); 此方法将返回输入字节的完全压缩版本,而不管压缩级别如何!!!

stamper.SetFullCompression();stamper.Writer.SetFullCompression(); 的目的/区别是什么?

使用不同压缩级别以便在每种情况下都能看到不同大小的正确方法是什么?

最佳答案

你有几个问题,我会尽力回答。

PdfStamper 是一个辅助类,它最终使用另一个名为 PdfStamperImp 的类来完成大部分工作。 PdfStamperImp 派生自 PdfWriter,当您使用 stamper.Writer 时,您实际上是在取回此实现类。 PdfStamper 上的许多属性也直接传递给实现类。所以这两个调用实际上做同样的事情。

stamper.SetFullCompression();
stamper.Writer.SetFullCompression();

另一个令人困惑的地方是 SetFullCompressionCompressionLevel 实际上根本不相关。 “完全压缩”表示在 PDF 1.5 中添加的称为“对象流”的功能,它允许将 PDF 对象组合在一起以潜在地允许更大的压缩。实际上并没有要求我们认为的“压缩”实际发生,但实际上我认为它总是会发生。 (可能一个 super 简单的文档可能会在启用此功能后变得更大,不确定并且不想测试。)

CompressionLevel 实际上是您通常认为的压缩,一个从 0 到 9 的数字或 -1 表示默认值(我认为目前等于 6)。该属性实际上是许多类最终派生自 PdfStream 类的一部分。但是,此设置不会“滴落”。由于您是通过 GetPageContent()SetPageContent() 从另一个位置导入流,因此该特定流有其自己的压缩设置,与 Writer 无关的压缩设置。实际上,您可以将第三个参数传递给 SetPageContent(),以根据需要设置特定的压缩级别。

reader.SetPageContent(1, reader.GetPageContent(1), PdfStream.BEST_COMPRESSION);

关于c# - 当我尝试压缩不同级别的 pdf 文件时,ITextSharp 返回相同大小的 pdf,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22019032/

相关文章:

c# - ExecuteStoreQuery 和 ExecuteStoreCommand 有什么区别

c# - Entity Framework 不一致 - 在这里工作,而不是那里

c# - 报表查看器未显示在表单设计器上(c# winform)

java - 避免在 Spring Rest 文件下载调用中使用 CoyoteOutputStream 对象签名

c - 用于 lzw 压缩的可变长度字符串数组

c - 如果 x>0 且 r(x) = 2x,则实现有符号到无符号映射 r(x)= 2x-1 的更快方法是什么

c# - 如何使 Xamarin 应用全屏(全屏)

pdf - 以编程方式从 Excel 数据填写 PDF 表单

php - 使用 phpSpreadsheet 将 Excel 转换为 pdf

java - 将输出膨胀到文件性能改进