6
\$\begingroup\$

I'm doing a application to work with PDF and TIFF files. To divide them, the user opens the file or folder (if it is a folder, it gets all the files inside) and the app splits the file, getting a tiny image (thumbnail) in JPG format. Then it creates a ListViewItem adding the thumbnail, the name and the size of the file.

But it takes too long (1:40min) with a PDF with 68 pages, so if a larger PDF is opened, it will take too long.

the time for 68 pages

So I wish someone could say where can I improve my code so it doesn't take that long.

CODE

public void SplitPDF2(string input)
{
    try
    {
        iTextSharp.text.pdf.PdfReader reader = new iTextSharp.text.pdf.PdfReader(input);
        iTextSharp.text.pdf.PdfReader.unethicalreading = true;
        string name = Path.GetFileNameWithoutExtension(input);
        for (int i = 1; i <= reader.NumberOfPages; i++)
        {
            using (MemoryStream ms = new MemoryStream())
            {
                //get thumbnail from 1st page-----------------------------------------------------                       
                using (var document = PdfiumViewer.PdfDocument.Load(input))
                {
                    var image = document.Render(i - 1, 60, 84, 300, 300, true);                            
                    image.Save(ms, ImageFormat.Jpeg);
                    thumbnails.Images.Add(j.ToString(), image);
                    image.Dispose();
                }
                //split pdf-----------------------------------------------------------------------
                string p = AppDomain.CurrentDomain.BaseDirectory + "temporario\\" + name + " - Pagina " + i + ".PDF";
                using (Stream outputStream = new FileStream(p, FileMode.Create))
                {
                    Document doc = new Document();
                    PdfWriter pdfWriter = PdfWriter.GetInstance(doc, outputStream);
                    doc.Open();
                    PdfContentByte pdfContentByte = pdfWriter.DirectContent;
                    PdfImportedPage importedpage = pdfWriter.GetImportedPage(reader, i);
                    iTextSharp.text.Rectangle mediabox = reader.GetPageSize(i);

                    doc.SetPageSize(mediabox);
                    doc.NewPage();
                    pdfContentByte.AddTemplate(importedpage, 0, 0);

                    doc.Close();
                    doc.Dispose();
                    pdfWriter.Dispose();
                }
                //in the end it will add the thumbnail, the name and the size of the file to the ListView 
                FileInfo f = new FileInfo(p);
                ListViewItem _item1 = new ListViewItem();
                _item1.ImageKey = j.ToString(); //image
                _item1.SubItems.Add(name + " - Pagina " + i + ".PDF"); //name
                _item1.SubItems.Add(f.Length.ToString()); //size

                lista2.Items.Add(_item1);
                j++;
            }
        }
        reader.Dispose();
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.ToString(), "Erro", MessageBoxButtons.OK);
    }
}
\$\endgroup\$
4
  • 3
    \$\begingroup\$ Why are you saving the images on the disk and not working with them in memory? You seem to mix a couple of principles there. using and Dispose at the same time, no using in other cases... quite a mess. \$\endgroup\$
    – t3chb0t
    Commented Apr 29, 2019 at 8:40
  • \$\begingroup\$ How should I do it using the memory? Using a MemoryStream? @t3chb0t \$\endgroup\$ Commented Apr 29, 2019 at 8:43
  • \$\begingroup\$ @t3chb0t Could you help me organizing and "unmessing" my code? \$\endgroup\$ Commented Apr 29, 2019 at 10:19
  • \$\begingroup\$ Welcome! You might want to take a look at profiling: docs.microsoft.com/en-us/visualstudio/profiling/?view=vs-2019 \$\endgroup\$
    – user50167
    Commented Nov 12, 2019 at 16:43

1 Answer 1

3
\$\begingroup\$

This code leaves a bunch of open questions, minor ones:
- SplitPDF2(string input) what has been/happened to SplitPDF() or SplitPDF1()?
- what is lista2?

Non-minor:

  • Document/comment your source code. In the code.
  • Preparing thumbnails and splitting a PDF into separate-file-per-page do neither sound nor look related:
    Do not put/implement both in a single procedure
  • I can't seem to see a purpose in saving each thumbnail rendered into a MemoryStream ms that doesn't get used otherwise.
  • You instantiate one and only one iTextSharp.text.pdf.PdfReader(input) for each input:
    Do the same for PdfiumViewer.PdfDocument
  • it will add the thumbnail I don't see that.

Overall, I'm left mistrusting writing file-per-page PDF to be a useful step in accomplishing the larger task at hand.
wish someone could say where [to improve the] code so it doesn't take that long my crystal ball is dull, but profiling/timeit() might help.

\$\endgroup\$
1
  • \$\begingroup\$ Thank you for your answer and I’m no longer working with that... since I am portuguese, some variables can be strange to you, such as “lista2”, my appologies. If I remember it well, the other SplitPDF() functions were with another libraries. I’m sure that who uses your answer to resolve their problems, it will help them. \$\endgroup\$ Commented Nov 13, 2019 at 16:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.