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

时间:2014-02-25 15:39:04

标签: c# pdf compression itextsharp

我正在阅读pdf并使用itextsharp注入一些内容。结果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();的目的/区别是什么?

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

2 个答案:

答案 0 :(得分:4)

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

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

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

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

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

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

答案 1 :(得分:0)

我正在使用下面的代码,并且没有被压缩。输出文件的大小也与输入文件的大小相同。

PdfReader reader = new PdfReader("/tmp/before.pdf");
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream("/tmp/temp.pdf"), PdfWriter.VERSION_1_5);

stamper.getWriter().setCompressionLevel(9);
int total = reader.getNumberOfPages() + 1;
for(int i=1;i<total;i++){
    reader.setPageContent(i, reader.getPageContent(i), PdfStream.BEST_COMPRESSION);
}

stamper.setFullCompression();
stamper.close();
reader.close();