0

The following code creates a .pdf first which is okay and looks perfect, I have taken the rest of the code (which makes the compression) from another post on this site. The problem is that the compressed.pdf file is 1kb and acrobat says the file is damaged and cannot be repaired. I have never made a pdf compressor before. Please, take a look at my code and if it is possible offer some corrections to make it working.

private void btnEndScan_Click(object sender, EventArgs e)
    {
        Document doc1 = new Document(PageSize.A4, 0, 0, 0, 0);
        string filename = "Prot_" + label.Text + ".pdf"; 
        try
        {
            PdfWriter.GetInstance(doc1, new FileStream("C:/" + filename, FileMode.Create));

            doc1.Open();
            for (int i = 0; i < imageArray.Length; i++)
            {
                iTextSharp.text.Image pic = iTextSharp.text.Image.GetInstance(imageArray[i], System.Drawing.Imaging.ImageFormat.Bmp);
                pic.ScalePercent(36f);
                doc1.Add(pic);
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show("Error creating pdf file" + ex);
        }
        finally
        {
            doc1.Close();

            PdfReader reader = new PdfReader("C:/" + filename);
            string filepath = "C:/compressed/" + filename;
            using (MemoryStream ms = new MemoryStream())
            {
                    PdfStamper stamper = new PdfStamper(reader, ms, PdfWriter.VERSION_1_5);
                    PdfWriter writer = stamper.Writer;
                    writer.CompressionLevel = PdfStream.BEST_COMPRESSION;
                    reader.RemoveFields();
                    reader.RemoveUnusedObjects();
                    stamper.Reader.RemoveUnusedObjects();
                    stamper.SetFullCompression();
                    stamper.Writer.SetFullCompression();
                    byte[] compressed = ms.ToArray();
                    reader.Close();
                    stamper.Close();
                    using (FileStream fs = File.Create("C:/compressed/compressed.pdf"))
                    {
                        fs.Write(compressed, 0, (int)compressed.Length);
                        fs.Close();
                    }
           }
        }
    }
joe_young
  • 4,107
  • 2
  • 27
  • 38

1 Answers1

1

You are cutting the file too short.

Take a look at these lines:

byte[] compressed = ms.ToArray();
reader.Close();
stamper.Close();

They should be ordered like this:

stamper.Close();
reader.Close();
byte[] compressed = ms.ToArray();

The order in your code is wrong because:

  • You should close the reader after the stamper, because the stamper may need access to the reader while closing.
  • The file is only complete when you close the stamper. At the moment you create the byte[] not all the PDF data has been written yet. The file is incomplete.

Because of the incomplete byte[], you are removing a substantial part of your file when you do this:

fs.Write(compressed, 0, (int)compressed.Length);

The value of compressed.Length is too short. Your actual file has a larger file size.

Bruno Lowagie
  • 75,994
  • 9
  • 109
  • 165
  • Thank you, seems i have still many things to learn. Changing lines order helped and the file is stored normally. There is no further compression after the above procedure, maybe this means there are no unused object or anything else unused in my pdf file. I am adding just scanned pages to the pdf in gif format, no text or anything besides. Is the result normal in this situation? – Vladimir Mihaylov Jul 13 '15 at 06:17
  • A PDF that contains nothing but images is hard to compress because most of the time the images are already compressed to the fullest. Reducing the resolution of the images is your only option, but that is something iText doesn't do automatically as iText doesn't want to degrade the images unintentionally. – Bruno Lowagie Jul 13 '15 at 08:43