(616) 371-1037

[email protected]

Rendering QR Codes on fillable PDFs

January 30, 2021 - John Waters

No Comments

I was recently working on a project where a fillable PDF form was populated with data and a QR code needed to be placed on the form. Here an easy way to accomplish that:

First, load the form – in this example I just read it from a file. I am using this two page vaccination card:

I have the PDF in my bin directory, so I’ll just read it into memory like this:

using System.IO;
var fileBytes = File.ReadAllBytes("VaccineCard.pdf");

To fill data fields and add images to the PDF, we will use the iTextSharp Nuget package:

https://www.nuget.org/packages/iTextSharp/5.5.4 

Once that package reference is added, I can set up a PdfReader and a Stamper from the iTextSharp namespace:

using System.IO;
using iTextSharp.text.pdf;

namespace ConsoleApp5
{
    class Program
    {
        static void Main(string[] args)
        {
            var fileBytes = File.ReadAllBytes("VaccineCard.pdf");
            using (var ms = new MemoryStream())
            {
                using (var reader = new PdfReader(fileBytes))
                {
                    using (var stamper = new PdfStamper(reader, ms))
                    {
                        ms.Write(fileBytes, 0, fileBytes.Length);
                    }
                }
            }
        }
    }

With the stamper, we can populate fillable fields using the AcroFields property. Here are the fields in the form I have loaded:

I will set a few values, and write the output to another file so we can see it:

stamper.AcroFields.SetField("First Name", "John");
stamper.AcroFields.SetField("Last Name", "Waters");
stamper.AcroFields.SetField("DOB", "1/1/2001");
stamper.AcroFields.SetField("Middle Init", "K");
// …
var output = ms.ToArray();
File.WriteAllBytes("VaccineCardFilled.pdf", output);

Here is the result:

That worked, great! Now let’s add a QR code.

For the QR codes, get the QRCoder Nuget, see https://github.com/codebude/QRCoder/

using QRCoder;

We will create a QR code for the value “123456789”. You can make QR codes out of any string – the more data the string contains, the larger and more complex the code becomes.

var qrGenerator = new QRCodeGenerator();
var qrCodeData = qrGenerator.CreateQrCode("123456789", QRCodeGenerator.ECCLevel.Q);
var qrCode = new Base64QRCode(qrCodeData);
var qrCodeImageAsBase64 = qrCode.GetGraphic(8);
var imageBytes = Convert.FromBase64String(qrCodeImageAsBase64);

If you look at the QRCoder documentation (link above), there are all kinds of ways to generate them. We will just do this simple image byte form. It uses a module size of 8 (8 dark pixels per square in the pattern). 

Next, I will place these generated QR code image bytes in an iTextSharp Image object, and set the width, height, X and Y coordinates of the image on the PDF. X starts from the left of the page, Y from the bottom of the page:

var img = Image.GetInstance(imageBytes);
img.ScaleAbsoluteWidth(40);
img.ScaleAbsoluteHeight(40);
img.SetAbsolutePosition(210, 165);

Finally, I will use the Stamper to place the image on an overlay of the form, on page 1:

stamper.GetOverContent(1).AddImage(img);

There it is!

To verify this, I will scan the QR code with RedLaser on my iPhone:

 

 

 

 

 

 

 

 

 

 

 

 

 

And there it is!

Here is the full code:

using System;
using System.IO;
using iTextSharp.text;
using iTextSharp.text.pdf;
using QRCoder;

namespace ConsoleApp5
{
    class Program
    {
        static void Main(string[] args)
        {
            var fileBytes = File.ReadAllBytes("VaccineCard.pdf");
            using (var ms = new MemoryStream())
            {
                using (var reader = new PdfReader(fileBytes))
                {
                    using (var stamper = new PdfStamper(reader, ms))
                    {
                        ms.Write(fileBytes, 0, fileBytes.Length);

                        stamper.AcroFields.SetField("First Name", "John");
                        stamper.AcroFields.SetField("Last Name", "Waters");
                        stamper.AcroFields.SetField("DOB", "1/1/2001");
                        stamper.AcroFields.SetField("Middle Init", "K");

                        var qrGenerator = new QRCodeGenerator();
                        var qrCodeData = qrGenerator.CreateQrCode("123456789", QRCodeGenerator.ECCLevel.Q);
                        var qrCode = new Base64QRCode(qrCodeData);
                        var qrCodeImageAsBase64 = qrCode.GetGraphic(8);
                        var imageBytes = Convert.FromBase64String(qrCodeImageAsBase64);

                        var img = Image.GetInstance(imageBytes);
                        img.ScaleAbsoluteWidth(40);
                        img.ScaleAbsoluteHeight(40);
                        img.SetAbsolutePosition(210, 165);

                        stamper.GetOverContent(1).AddImage(img);
                    }
                }
                var output = ms.ToArray();
                File.WriteAllBytes("VaccineCardFilled.pdf", output);
            }
        }
    }
}

Hopefully this will come in handy next time you need to add a QR code to a form!

John Waters

Leave a comment

Your email address will not be published. Required fields are marked *