Click here to Skip to main content
15,867,308 members
Articles / Programming Languages / C#

PDF417 Barcode Encoder Class Library and Demo App Ver. 2.2

Rate me:
Please Sign up or sign in to vote.
5.00/5 (21 votes)
8 Sep 2020CPOL12 min read 57.5K   4.1K   51   51
The PDF417 barcode encoder class library is written in C#. The target framework is .NET Framework (net462) and .NET Standard (netstandard2.0). The encoder library allows you to create a PDF417 barcode image from a text string or a binary (byte) array. Two demo/test applications are included.
This article explains how to install the software. How to integrate the encoder library to your application and produce a barcode image. And how to use the demo/test programs.

Pdf417EncoderIcon

Introduction

The PDF417 barcode encoder class library is written in C#. It is open source code. The target framework is .NET Framework (net462) and .NET Standard (netstandard2.0). The encoder library allows you to create a PDF417 barcode image from a text string or a binary (byte) array. Two demo/test applications are included. Windows form application and console application targeting .NET framework (net462) and .NET Core (netcoreapp2.2). Both allow you to explore the library and produce PDF417 barcodes.

Both .NET core and .NET standard do not support the Bitmap class included in the System.Drawing assembly. The library includes a PNG image builder that can run in the .NET Standard and .NET core environment. This image is extremely efficient. It takes advantage of the compression and filtering of the PNG standard. Saving barcode image 564 by 232 pixels takes 617 bytes by this software. Using Bitmap with file type PNG takes 16,865. Using Bitmap with file type JPEG takes 21,121 bytes.

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 software converts the 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 varies 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 library and two demo/test programs. This article explains how to install the software. How to integrate the encoder library to your application and produce a barcode image. And how to use the demo/test programs.

Adding PDF417 Barcode to Your Application Overview

Adding PDF417 barcode to your PDF document must follow the steps below.

Option 1: Using the Pdf417Encoder Class

  • Create Pdf417Encoder object.
  • 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 PNG file or a Bitmap image of your barcode.

Option 2 Using the Pdf417CommandLine Class

Use the command line class to create a PNG file using one input text string to set all the options.

Simple Example of Creating PDF417 Barcode with Option 1

C#
// test string to be encoded
string Text = "Pdf417EncoderDemo - Rev 2.0.0 - 2019-05-07 \u00a9 2019 Uzi Granot. 
               All rights reserved.";

// create PDF417 barcode object
Pdf417Encoder Encoder = new Pdf417Encoder();

// change default data columns
Encoder.DefaultDataColumns = 4;

// encode barcode data
Encoder.Encode(Text);

// save barcode image to PNG file
Encoder.SaveBarcodeToPngFile("path\\FileName.png");

Simple Example of Creating PDF417 Barcode with Option 2

C#
// InputTextFile is the text file to encode
// OutputImage.png is the result
CommandLine.Encode("/col=4 /t path\\InputTextFile path\\OutputImage.png");

Adding the PDF417Encoder Class 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.

PDF417Barcode Object

Create PDF417 barcode object. This object can be reused serially to produce multiple barcodes.

C#
// create PDF417 barcode object
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.

C#
// all three segments types are in consideration
Encoder.EncodingControl = EncodingControl.Auto;
// all input is one segment and it is bytes
Encoder.EncodingControl = EncodingControl.ByteOnly;
// input is divided into text and byte segments
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 improve 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.

C#
Encoder.ErrorCorrection = ErrorCorrectionLevel.Level_0;    // up to Level_8
// or
Encoder.ErrorCorrection = ErrorCorrectionLevel.AutoNormal; // default
// or
Encoder.ErrorCorrection = ErrorCorrectionLevel.AutoLow;    // one less than normal
// or
Encoder.ErrorCorrection = ErrorCorrectionLevel.AutoMedium; // one more than normal
// or
Encoder.ErrorCorrection = ErrorCorrectionLevel.AutoHigh;   // two more than normal

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.

C#
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 NarrowBarWidth value.

C#
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 NarrowBarWidth

C#
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.

C#
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.

C#
// n must be 1 to 9 or 13 or 15
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.

C#
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.

C#
Encoder.GlobalLabelIDGeneralPurpose = value;

Encoding Data

There are two encoding methods. One accepts text string as an input argument and the other one accepts byte array as an input argument.

C#
// encoding text string
Encoder.Encode(string StringData);

// encoding binary byte array
Encoder.Encode(byte[] BinaryData);

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 controls 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. In step one, the string is converted to UTF8 byte array. In 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.

C#
// This is the source code of the Encode(string) method.
// It is provided here in case you want to modify it to suit your special need.
public void Encode(string StringData)
{
// convert string to UTF8 byte array
byte[] UtfBytes = Encoding.UTF8.GetBytes(StringData);

// convert UTF8 byte array to ISO-8859-n byte array
Encoding ISO = Encoding.GetEncoding(_GlobalLabelIDCharacterSet ?? "ISO-8859-1");
byte[] IsoBytes = Encoding.Convert(Encoding.UTF8, ISO, UtfBytes);

// call the encode binary data method
Encode(IsoBytes);
Return;
}

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)
  • Encoder.DataRows

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: NarrowBarWidth, RowHeight or QuietZone values.

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.

C#
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.

C#
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.

C#
bool Encoder.SetDataRows(int Rows);

Save PDF417 Barcode to a PNG File or a Stream

C#
// save the barcode to a disk file
Encoder.SaveBarcodeToPngFile("FileName");

// or
// save the barcode to an Output Stream
Encoder.SaveBarcodeToPngFile(OutputStream);

Save PDF417 Barcode to a Bitmap File or a Stream

C#
// save the barcode to a disk file
// ImageFormat such as PNG, BMP, JPEG
Encoder.SaveBarcodeToFile("FileName", ImageFormat);

// or
// save the barcode to an Output Stream
// ImageFormat such as PNG, BMP, JPEG
Encoder.SaveBarcodeToFile(OutputStream, ImageFormat);

Create PDF417 Barcode Bitmap Image

C#
// Create Bitmap object
Bitmap Image = Encoder.CreateBarcodeBitmap();

// or
// Create Bitmap image with white and black brushes
// This allows you to change the color of the background
// and the bars
Bitmap Image = Encoder.CreateBarcodeBitmap(WhiteBrush, BlackBrush);

Create PDF417 Boolean Matrix Where Each Element Represents a Pixel

C#
// Boolean image
// Black is true
// White is false
bool[,] ConvertBarcodeMatrixToPixels();

Create PDF417 Boolean Matrix Where Each Element Represents a Bar

This method is automatically executed for each of the methods described above.

C#
// Boolean image
// Black is true
// White is false
bool[,] CreateBarcodeMatrix();

Create PNG Image File using the CommandLine Class

The command line arguments are described below. A more detailed description of each option is given above.

C#
Command line arguments format
[optional arguments] input-file output-file
Output file must have .png extension
Options format /code:value or -code:value (the : can be =)
Encoding control. code=[encode|n], value=[auto|a|byte|b|text|t], default=a
Error correction level. code=[error|e], value=[0-8|low|l|normal|n|medium|m|high|h], default=n
Narrow bar width. code=[width|w], value=[1-100], default=2
Row height. code=[height|h], value=[3-300], default=6, min=3*width
Quiet zone. code=[quiet|q], value=[2-200], default=4, min=2*width
Layout options. Only one of data columns, data rows or image ratio
Data columns. code=[col|c], value=[1-30], default=3
Data rows. code=[row|r], value=[3-90], no default
Image ratio (width/height). code=[ratio|o], value=[decimal > 0], no default
Text file format. code=[text|t], value=iso-8859-n, see notes below
Input file is binary unless text file option is specified
If input file format is text or t with no value, character set is iso-8859-1
If input file format is text or t value must be iso-8859-n and n must be 1-9, 13, 15

Demo/Test Program

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.

Pdf417EncoderDemo

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 lets 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.

Pdf417EncoderAdjust

Press “Save PNG” to save the barcode to a disk file in PNG format. This method of saving the image is significantly more efficient than saving it with Bitmap.

Press “Save” 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.

Pdf417EncoderSave

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 color 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. And 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.

Pdf417BarcodeRotate10

In the second one, the barcode is viewed in perspective.

Pdf417BarcodePerspective

The Source Code

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 CalculateErrorCorrection
  • Converting the combined data array and error correction array into black and white Boolean matrix. The main method is CreateBarcodeMatrix. Each element represents one narrow bar. Black is true, white is false.
  • Saving the barcode matrix into PNG file without the use of Bitmap class. The main method is SaveBarcodeToPngFile. This method is very efficient in terms of compressing the image into a file. It takes advantage of the filtering and compression capabilities of the PNG standard.

Installation

The attached Visual Studio solution source file includes three projects:

  • Pdf417EncoderLibrary - The encoder library consists of a number of classes The main class is. Pdf417Encoder.
  • Pdf417EncoderDemo - The demo program allows you to test the encoder and try out all the control options available. You can save the result with either Save PNG button or the Save 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.
  • PdfConsoleDemo - The console demo program was design to test the .NET core environment.

Integrating the Pdf417EncoderLibrary to your application.

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 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 (.exe) file.

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.

History

  • 2019/04/01: Version 1.0 - Original version
  • 2019/04/15: Version 1.1 - Fix for Visual Studio 2019 security block
  • 2019/05/07: Version 2.0 - Major changes to support .NET core and .NET standard. As well as saving the image in PNG format without using Bitmap class
  • 2019/05/15: Version 2.1 - Minor changes to source code
  • 2020/09/08: Version 2.2 - Fix for out of memory error

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Canada Canada
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
Questioncharacter sequence Pin
Member 1555456710-Mar-22 15:56
Member 1555456710-Mar-22 15:56 
AnswerRe: character sequence Pin
Uzi Granot11-Mar-22 2:30
Uzi Granot11-Mar-22 2:30 
GeneralRe: character sequence Pin
Member 1555456711-Mar-22 7:50
Member 1555456711-Mar-22 7:50 
QuestionBarcode to Bitmap Pin
Member 153436592-Sep-21 2:33
Member 153436592-Sep-21 2:33 
AnswerRe: Barcode to Bitmap Pin
Uzi Granot2-Sep-21 3:49
Uzi Granot2-Sep-21 3:49 
GeneralRe: Barcode to Bitmap Pin
Member 153436592-Sep-21 4:05
Member 153436592-Sep-21 4:05 
GeneralRe: Barcode to Bitmap Pin
Uzi Granot2-Sep-21 7:50
Uzi Granot2-Sep-21 7:50 
GeneralRe: Barcode to Bitmap Pin
Member 153436592-Sep-21 8:05
Member 153436592-Sep-21 8:05 
GeneralMy vote of 5 Pin
Jacquers11-Dec-20 1:26
Jacquers11-Dec-20 1:26 
GeneralRe: My vote of 5 Pin
Uzi Granot11-Dec-20 4:50
Uzi Granot11-Dec-20 4:50 
GeneralMy vote of 5 Pin
LightTempler9-Sep-20 9:26
LightTempler9-Sep-20 9:26 
GeneralMy vote of 5 Pin
Member 137041438-Sep-20 23:48
Member 137041438-Sep-20 23:48 
QuestionEncoding multiple barcodes Pin
Member 1376887212-Aug-20 1:18
Member 1376887212-Aug-20 1:18 
AnswerRe: Encoding multiple barcodes Pin
Uzi Granot12-Aug-20 3:53
Uzi Granot12-Aug-20 3:53 
GeneralRe: Encoding multiple barcodes Pin
Member 1376887212-Aug-20 11:07
Member 1376887212-Aug-20 11:07 
Thanks for the quick reply.Thumbs Up | :thumbsup:
What I did is that I only used
Encoder.Encode(text);
then decoded it with your code. I encoded a single string like 000002280001 then the decoder returned the exact text value from the barcode image that your encoder produced.
I think now I get it. Please correct anything that you think is wrong:

The actual barcode value is not the original values that are encoded into the PDF417. They are like a print or encryption of the original text. So, When I encoded 000002280001 The actual value of the barcode is different since the encoder encodes it.

If I am to code something like:
BP111 FictionalFirstName A01 C01 B02 .
Which means passenger FictionalFirstName will travel from A01 to C01 and B02 it then will be encoded into different smaller sized text. (This is just a fictional standard to encode the information)
All I need to do is gathering all the information in a single text value and pass it to your encoder and then the encoder will take care of it right?

In order to generate the text that contains all these info and symbols, the text have to be created using the tables in IATA document right?

I will use the encoder with the example in the document and see what I can get.

Thanks again

Regards
Shada

GeneralRe: Encoding multiple barcodes Pin
Uzi Granot12-Aug-20 14:23
Uzi Granot12-Aug-20 14:23 
GeneralRe: Encoding multiple barcodes Pin
Member 137688722-Sep-20 12:16
Member 137688722-Sep-20 12:16 
GeneralRe: Encoding multiple barcodes Pin
Uzi Granot2-Sep-20 12:32
Uzi Granot2-Sep-20 12:32 
QuestionPDF417 Encode Out Of Memory Pin
Aminuddin Johari14-Oct-19 22:12
Aminuddin Johari14-Oct-19 22:12 
AnswerRe: PDF417 Encode Out Of Memory Pin
Uzi Granot16-Oct-19 9:25
Uzi Granot16-Oct-19 9:25 
GeneralRe: PDF417 Encode Out Of Memory Pin
Member 146609911-Dec-19 23:32
Member 146609911-Dec-19 23:32 
GeneralRe: PDF417 Encode Out Of Memory Pin
Uzi Granot2-Dec-19 4:06
Uzi Granot2-Dec-19 4:06 
QuestionRe: PDF417 Encode Out Of Memory Pin
yang chen7-Sep-20 21:42
yang chen7-Sep-20 21:42 
AnswerRe: PDF417 Encode Out Of Memory Pin
Uzi Granot8-Sep-20 6:07
Uzi Granot8-Sep-20 6:07 
AnswerRe: PDF417 Encode Out Of Memory Pin
Uzi Granot8-Sep-20 14:45
Uzi Granot8-Sep-20 14:45 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.