Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
654 views
in Technique[技术] by (71.8m points)

c# - ITextSharp returning same size pdf when I'm trying to compress pdf file with different levels

I'm reading a pdf and injecting some content using itextsharp. The resulting byte[] is passed to the method below along with the compression level.

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;
            }
        } 

If I comment stamper.SetFullCompression(); then this method is returning same size of byte array irrespective of the compression level am passing(am passing from 0 to 9 in each case)..

If I uncomment stamper.SetFullCompression(); this method is returning fully compressed version of the input byte irrespective of the compression level!!!

What is the purpose/difference of stamper.SetFullCompression(); and stamper.Writer.SetFullCompression();?

What is the correct way to use different compression levels so that I can see different sizes in each case?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You have a couple of questions and I'll try my best to answer them.

PdfStamper is a helper class that ultimately uses another class called PdfStamperImp to do most of the work. PdfStamperImp is derived from PdfWriter and when you use stamper.Writer you are actually getting back this implementation class. Many of the properties on PdfStamper also pass directly through to the implementation class. So these two calls actually do the same thing.

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

Another point of confusion is that SetFullCompression and the CompressionLevel aren't actually related at all. "Full compression" represents a feature that was added in PDF 1.5 called "Object Streams" that allows grouping PDF objects together to potentially allow for greater compression. There's actually no requirement that what we think of as "compression" actually occurs but in reality I think it would always happen. (Possibly a super simple document might get larger with this enabled, not sure and don't feel like testing.)

The CompressionLevel is actually what you normally think of as compression, a number from 0 to 9 or -1 to mean default (which currently equals six I think). This property is actually part of the PdfStream class which many classes ultimately derive from. This setting doesn't "trickle down", however. Since you are importing a stream from another location via GetPageContent() and SetPageContent() that specific stream has its own compression settings unrelated to the Writer's compression settings. There's actually a third parameter that you can pass to SetPageContent() to set your specific compression level if you want.

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...