PDF417 is a two-dimensional barcode. The barcode documentation and specification can be found in the following websites: Wikipedia provides a good introduction to PDF417. Click here to access the page. The PDF417 standard can be purchased from the ISO organization at this website. An early version of the specifications is freely available to be downloaded at this website. I strongly recommend that you download this document if you want to fully understand the encoding options.
The PDF417 barcode encodes text or binary array of bytes into an image of black and white bars. The attached open source software written in C# for .NET framework will perform this conversion of text or binary array into a PDF417 barcode Bitmap image. If the input data is a text string it will first be converted to a binary array using ISO 8859-n standard as defined here.. The binary array of bytes is converted to codewords. Each codeword is a number in the range of 0 to 928. This conversion process divides the input bytes into segments. There are three types of segments: text, bytes and numeric. Each segment type is compressed: text as 2 data characters per codeword, byte as 1.2 data characters per codeword and numeric as 2.93 data characters per codeword. To ensure barcode integrity, error correction and detection codewords are appended to the data codewords. There are 9 levels of error correction. The codewords are divided into rows and columns. Each codeword is converted to a symbol, sequence of alternating four black and four white bars. A narrow bar is a module. In total there are 17 modules for each codeword. Bar width vary from one to six modules. Each codeword is translated into one of three symbols. Symbol 1 is for row 1, 4, 7 etc. symbol 2 is for row 2, 5, 8 etc. and symbol 3 if for rows 3, 6, 9 etc.
The software attached to this article is a PDF417 Encoder and a demo/test program. This article explains how to install the software. How to integrate the encoder to your application and produce a Bitmap image. And how to use the demo/test program.
Adding PDF417 Barcode to Your Application Overview
Adding PDF417 barcode to your PDF document must follow the steps below.
- Set encoding options. All encoding options have default values.
- Encode a text data string or a binary data bytes array.
- Check the resulted image width and image height. Or, check the number of data columns and data rows. Make sure the image size or aspect ratio is appropriate for your application. If it is not, adjust the layout.
- Create a
Bitmap image of your barcode.
Simple example of creating PDF417 Barcode
string Text = "Pdf417EncoderDemo - Rev 1.0.0 - 2019-04-01 \u00a9 2019 Uzi Granot. All rights reserved.";
Pdf417Encoder Encoder = new Pdf417Encoder();
Encoder.DefaultDataColumns = 4;
Bitmap Image = Encoder.CreateBarcodeImage();
Adding PDF417 Barcode to Your Application Details
Below you will find a description of all public properties and methods. They are organized in the logical order for processing.
Create PDF417 barcode object. This object can be reused serially to produce multiple barcodes.
Pdf417Encoder Encoder = new Pdf417Encoder();
Encoding Control (Default is Auto)
The PDF417 encoder encodes Input bytes into codewords. There are three types of codewords: byte, text and numeric. The program has an algorithm to divide the data input into segments. Each segment is one of these three types. Each segment is compressed to reduce barcode size. The default is Auto. However, you can restrict the segmentation to only bytes or only text and bytes.
Encoder.EncodingControl = EncodingControl.Auto;
Encoder.EncodingControl = EncodingControl.ByteOnly;
Encoder.EncodingControl = EncodingControl.TextAndByte;
Error Correction Level (Default is AutoNormal)
The PDF417 adds error correction codewords to detect errors and correct them. More error correction codewords improves the reliability of the barcode. However, it makes the barcode bigger. Error correction level allows you to control the quality of the barcode. The
ErrorCorrectionLevel enumeration has two types of values. Fixed levels from 0 to 8. And relative levels that are recommended values based on the number of data codewords. For more details look at Table 6 and Table 7 in the PDF417 Specification.
Encoder.ErrorCorrection = ErrorCorrectionLevel.Level_0;
Encoder.ErrorCorrection = ErrorCorrectionLevel.AutoNormal;
Encoder.ErrorCorrection = ErrorCorrectionLevel.AutoLow;
Encoder.ErrorCorrection = ErrorCorrectionLevel.AutoMedium;
Encoder.ErrorCorrection = ErrorCorrectionLevel.AutoHigh;
Narrow Bar Width (Default is 2)
The width in pixels of a narrow barcode bar. It is also called module in the specifications. If this value is changed, the program makes sure that
RowHeight is at least three times that value. And that
QuietZone is at least twice that value. If you expect the barcode to be scanned by a camera, and the barcode could be rotated with respect to the camera image coordinates, I would recommend narrow bar width to be at least 4.
Encoder.NarrowBarWidth = value;
Row Height (Default is 6)
The height in pixels of one row. This value must be greater than or equal to 3 times the
Encoder.RowHeight = value;
Quiet Zone (Default is 4)
The width of the quiet zone all around the barcode. The quiet zone is white. This value must be greater than or equal to 2 times the
Encoder.QuietZone = value;
Default Data Columns (Default is 3)
The default data columns value. The value must be in the range of 1 to 30. After the input data is encoded, the software sets the number of data columns to the default data columns and calculates the number of data rows. If the number of data rows exceeds the maximum allowed (90), the software sets the number of rows to the maximum allowed and recalculate the number of data columns. If the result is greater than the maximum columns allowed, an exception is thrown.
Encoder.DefaultDataColumns = value;
Global Label ID Character Set (Default is null)
Set Global Label ID Character Set to ISO 8859-part standard. The part can be 1 to 9, or 13, or 15. If the string is null, this value will not be part of the barcode data. However, most decoders will take it as ISO-8859-1. Language support is defined here.
Encoder.GlobalLabelIDCharacterSet = "ISO-8859-n";
Global Label ID User Defined (Default is 0)
Set Global Label ID user defined value. If user defined value is zero, it is not included in the barcode. User defined value must be between 810900 and 811799. The value stored in the barcode will be 0 to 899 for the above range. In other words: stored_value = value – 810900;. My suggestion is, do not set this value unless you know that your expected decoder can handle it.
Encoder.GlobalLabelIDUserDefined = value;
Global Label ID General Purpose (Default is 0)
Set Global Label ID general purpose value. If general purpose value is zero, it is not included in the barcode. General purpose value must be between 900 and 810899. The value will be stored in two code words. The first one Value / 900 – 1. The second one Value % 900. My suggestion is, do not set this value unless you know that your expected decoder can handle it
Encoder.GlobalLabelIDGeneralPurpose = value;
There are two encoding methods. One accepts text string as an input argument and the other one accepts byte array as an input argument.
The barcode was designed for binary data. Therefore, the first method above must convert the string from 16 bits characters to byte array. The Encode(string) method has the following conversion logic. The Global Label ID Character Set property control the conversion. If your conversion requires ISO-8859-n where n is not one, you must set the character set property before the encode method is called. The conversion is done in two steps. Step one the string is converted to UTF8 byte array. Step two the UTF8 byte array is converted to ISO-8859-n byte array. For example, if you want to encode Hebrew text you should set the character set to ISO-8859-8.
public void Encode(string StringData)
byte UtfBytes = Encoding.UTF8.GetBytes(StringData);
Encoding ISO = Encoding.GetEncoding(_GlobalLabelIDCharacterSet ?? "ISO-8859-1");
byte IsoBytes = Encoding.Convert(Encoding.UTF8, ISO, UtfBytes);
Barcode Size and Aspect Ratio
After the data was encoded and before the barcode image was created, you can check the overall size of the barcode. If the barcode size or aspect ratio are not what you want, you can modify them to suit your needs. The Pdf417Encoder gives you four properties values:
- Encoder.ImageWidth in pixels (including quiet zone)
- Encoder.ImageHeight in pixels (including quiet zone)
- Encoder.DataColumns (excluding start and stop symbols and left and right row indicators)
If you want to adjust the layout of the barcode you can used one of the methods below. In addition, you can readjust the optional parameters:
Width to Height Ratio
This method will calculate the number of data rows and data columns to achieve a desired width to height ratio. The ratio includes the quiet zone. The result will be equal or close to your request. Check the return value for success.
bool Encoder.WidthToHeightRatio(double Ratio);
Set Data Columns
This method will calculate the number of data rows based on the desired number of data columns. Check the return value for success.
bool Encoder.SetDataColumns(int Columns);
Set Data Rows
This method will calculate the number of data columns based on the desired number of data rows. Check the return value for success.
bool Encoder.SetDataRows(int Rows);
Create PDF417 Barcode image
The final step is the creation of barcode image. There are four variation of image creation.
Option 1: Create barcode image with no arguments. The return value is
Bitmap Image = Encoder.CreateBarcodeImage();
Option 2: Create barcode image to be saved as disk file.
Encoder.CreateBarcodeImage(string FileName, ImageFormat Format);
Option 3: Create barcode image in two steps. The first step is the creation of bool matrix. Each element is a module. The matrix does not include the quiet zone. Second step is creation of
Bitmap. The first method above is the combination of these two steps.
bool[,] Pdf417Matrix = Encoder.CreateBWMatrix();
Bitmap Image = Encoder.CreateBarcodeImage(Pdf417Matrix);
Option 4: Create black and white image in bool[,] matrix in two steps. The first step is the creation of bool matrix. Each element is a module. The matrix does not include the quiet zone. Second step is creation of bool[,] matrix. In this bool[,] matrix each element corresponds to one pixel. Quiet zone is included. This method is included to support another article. PDF File Writer C# Class Library (Version 1.22.0)
bool[,] Pdf417Matrix = Encoder.CreateBWMatrix();
bool[,] Pdf417BWImage = Encoder.CreateBWImage(Pdf417Matrix);
The Pdf417EncoderDemo project was designed to demonstrate and test all the features of the PDF417 Encoder Library. It can be used as a source for code examples.
At the top left side you can set all the encoding options. At the bottom above the buttons you enter the text to be encoded. The program has built in examples of text in different languages. The combo-box at the bottom right let you select one of these examples. The “Load File” button allows you to load your own example from a file.
Pressing the “Encode” button will convert the text on the screen to a PDF417 barcode. The barcode will be displayed. Note: you can resize the screen to see it in more details.
If you want to change the aspect ratio of the barcode, press “Adjust Layout”. The screen below will be displayed. Select one of the options to set the rows and columns. Click OK. The new layout will be displayed.
Press “Save Image” to save the barcode to the disk. The screen below will be displayed. If you want to save the barcode as is, press “Save” and select file name and folder.
If you want to save the barcode over a background, select either “Brush” radio button or “Image” radio button. For brush background you can select colour and texture. For image background you must load one of your own pictures. In both cases you can set the position of the barcode. You can rotate the barcode. Ad you can display it in perspective. These options plus error spots are included for testing of PDF417 decoders.
Two examples of barcode over background are given below. In the first one the barcode is rotated.
In the second one the barcode is viewed in perspective.
The Source Code
The Pdf417Encoder Library consists of one class. All the public methods of this class are described above in the “Adding PDF417 Barcode to Your Application Details” section.
The internal code can be divided into the following segments:
- Encoding input data into codewords. The main method is
DataEncoding. The Encoding data algorithm is described in Appendix D (Informative) Encoding Data of the USS-PDF-417 document.
- Calculating error correction and detection array of codewords. The main method is
- Converting the combined data array and error correction array into black and white Boolean matrix. The main method is
CreateBWMatrix. Each element represents one narrow bar. Black is true, white is false.
- Converting the black and white Boolean matrix into black and white image matrix. The main method is
CreateBWImage. Each element represents one pixel.
- Converting the black and white image matrix to
Bitmap. The main method is
The attached Visual Studio solution source file includes two projects:
Pdf417EncoderLibrary The encoder library consists of one class
Pdf417Encoder. This class has all the tools to convert your data input into
Pdf417EncoderDemo The demo program allows you to test the encoder and try out all the control options available. You can save the result with The Save Image button. In addition to plain save, the demo program is made to produce images over background, rotated images and perspective images. You can add error spots. These features were made for testing a Pdf417 decoder.
There are two ways to integrate the
Pdf417EncoderLibrary to your application.
- Add the
Pdf471Encoder class to your own code. You can do it if your application is written in C#. Since this library consists of one source file with one class, this is the preferred way.
- Include the
Pdf417EncoderLibrary.dll class library with your project. If your project is a Visual Basic, you must do it this way. Install the attached
Pdf417EncoderLibrary.dll file in your development area. Start Visual Studio. Open your application. Go to the Solution Explorer. Right click on References and select Add Reference. Select the Browse tab and navigate your file system to the location of the installed
Pdf417EncoderLibrary.dll. When your application is published, the file
Pdf417EncoderLibrary.dll must be included and installed in the same folder as your executable (
The namespace of the
Pdf471Encoder class is
Pdf417BarcodeLibrary . Add a "
using" statement to all your source files referring to this library: Or, change the namespace to your own namespace.
- 2019/04/01: Version 1.0 Original version
- 2019/04/15: Version 1.1 Fix for Visual Studio 2019 security block