Using Visual Basic to Create PDFs from Images

PDF files have become part and parcel of being able to use a computer productively. PDF (Portable Document Format) is a file format used to present documents independent of application software, hardware, and operating systems. A PDF file contains a complete description of a fixed-layout flat document, as well as fonts, text, and graphics. Today, I will show you how to convert images to a PDF document and how to combine two PDF documents into one.


PDFsharp is an Open Source library that creates PDF documents from any .NET language. PDFSharp can use either GDI+ or WPF and it includes support for Unicode in PDF files. Download PDSharp here and you can find a few samples here to get you started.

Our Project

Create a new Visual Basic Windows Forms project. Feel free to name it anything you like, but keep in mind that my objects may be named differently. All you need to add to the form is a BackgroundWorker object. Make sure that you have downloaded PDFSharp and add a Reference to it in the Project, Add References box, as shown in Figure 1:

Figure 1: References

Add the following namespaces to your code:

Imports System.Windows.Forms
Imports System.Configuration
Imports System.IO
Imports PdfSharp.Drawing
Imports PdfSharp.Pdf
Imports PdfSharp.Pdf.IO
Imports System.Threading

The references to PdfSharp are necessary because we will be using capabilities from each library in our project. We reference it here as well so that we can properly make use of each library inside our project. Add the following private variable:

   Private _sync As SynchronizationContext = _

The SynchronizationContext object will allow one thread to communicate with another thread. Have a look here for a better explanation.

Add the following code into your Form's Load event:

   Private Sub frmPOD_Load(sender As Object, e As EventArgs)
      _sync = System.Threading.SynchronizationContext.Current
   End Sub

The BackgroundWorker object gets started in the Form Load event. Add the following code:

   Private Sub worker_DoWork(sender As Object, e As DoWorkEventArgs)


         For Each file As String In Directory.GetFiles _
            ("C:\PDF Files To Import")

            ConvertPDF(file.ToString(), "C:\File.pdf")
            CombinePDF(file.ToString(), "PDF File2.pdf")
      Catch ex As System.Exception
      End Try
   End Sub

The DoWork event loops through a supplied directory (C:\PDF Files To Import) and calls the ConvertPDF and CombinePDF subs for each file in the directory, respectively. Add the ConvertPDF sub procedure now:

   Private Sub ConvertPDF(_srcFile As String, _destFile As String)

         Dim srcFile = _srcFile
         Dim destFile = (Convert.ToString(Path.GetDirectoryName(srcFile) + _
            "\") & _destFile) + ".pdf"

         Dim doc As New PdfDocument()

         doc.Pages.Add(New PdfPage())
         Dim xgr As XGraphics = XGraphics.FromPdfPage(doc.Pages(0))
         Dim img As XImage = XImage.FromFile(srcFile)

         xgr.DrawImage(img, 0, 0)



         LogError(Nothing, "PDF Created: " + _
      Catch ex As Exception
      End Try
   End Sub

The ConvertPDF sub procedure takes two arguments: one for the source file, which will be converted to a PDF document; and the resulting file, which will be saved at the same location as the input document. A PdfDocument gets created and instantiated. A Page gets added to the newly created PDF document. The XGraphics object draws an XImage object, which hosts the image file that was supplied onto the PDF page. Lastly, the PDF document gets saved.

Now, add the CombinePDF sub:

   Private Sub CombinePDF(ExistingPDF As String, NewPDF As String)
         Dim outputDocument As PdfDocument = PdfReader.Open(NewPDF)
         Dim inputDocument As PdfDocument = PdfReader.Open(ExistingPDF, _
         Dim count As Integer = inputDocument.PageCount

         For idx As Integer = 0 To count - 1
            Dim page As PdfPage = inputDocument.Pages(idx)



         LogError(Nothing, "PDF Created: " + Path.GetFileName(NewPDF))
      Catch ex As Exception
      End Try
   End Sub

The CombinePDF sub takes two arguments as well: one for the input document and one for the output document. First, the Output document gets opened up in memory. An Input document then gets created and indicates that it will be used as an Import document. A Loop gets created and it loops through all the pages inside the input document and adds them one by one into the output document. Lastly, the resulting document gets physically saved under a supplied name.

You will notice that, inside the Catch block, a sub procedure named LogError gets called. Let's add that now:

   Private Sub LogError(ex As Exception, Optional msg As String = "")
      If ex Is Nothing Then
         Dim message As String = String.Format("Time: {0}", _
            DateTime.Now.ToString("dd/MM/yyyy hh:mm:ss tt"))
         message += Environment.NewLine
         message += String.Format("Message: {0}", msg)

         Dim path As String = ErrorLogLocation & _
         Using swriter As New StreamWriter(path, True)
         End Using

         Dim message As String = String.Format("Time: {0}", _
            DateTime.Now.ToString("dd/MM/yyyy hh:mm:ss tt"))
         message += Environment.NewLine
         message += "-----------------------------------------------------------"
         message += Environment.NewLine
         message += String.Format("Message: {0}", ex.Message)
         message += Environment.NewLine
         message += String.Format("StackTrace: {0}", ex.StackTrace)
         message += Environment.NewLine
         message += String.Format("Source: {0}", ex.Source)
         message += Environment.NewLine
         message += String.Format("TargetSite: {0}", ex.TargetSite.ToString())
         message += Environment.NewLine
         message += "-----------------------------------------------------------"
         message += Environment.NewLine
         Dim path As String = ErrorLogLocation & _
         Using writer As New StreamWriter(path, True)
         End Using
      End If
   End Sub

This sub serves a dual purpose. The first is obviously to log a detailed exception and the other is simply to display a message that gets supplied.


PdfSharp is very powerful and easy to use with the .NET Framework, as you can see. It makes any file conversion into a PDF format very quick and easy.

About the Author

Hannes DuPreez

Hannes du Preez is a Microsoft MVP for Visual Basic for the eighth consecutive year. He loves technology and loves Visual Basic. He has a lot of experience in .NET and loves to share his love, pain and musings about Visual Basic

Related Articles


  • There are no comments yet. Be the first to comment!

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

Most Popular Programming Stories

More for Developers

RSS Feeds

Thanks for your registration, follow us on our social networks to keep up-to-date