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

QR Code Encoder and Decoder C# Class Library for VS 2022 .NET 6.0 (Version 3.1.0)

Rate me:
Please Sign up or sign in to vote.
4.97/5 (156 votes)
17 Mar 2022CPOL12 min read 322K   45.7K   340   170
QR Code libraries to allow program to create QR Code image or read image containing one or more QR Codes
The QR Code libraries allows your program to create (encode) QR Code image or, read (decode) an image containing one or more QR Codes. The code was upgraded to VS 2022 and .NET 6.0.

QRCodeLibrary Icon

Introduction

The QR Code libraries allows your program to create (encode) QR Code image or, read (decode) an image containing one or more QR Codes. The attached source code is made of two solutions, a QR Code encoder solution and a QR Code decoder solution. The software was upgraded to VS 2022 .NET6.0. The source code is written in C#. It is an open-source code.

Please note the word "QR Code" is registered trademark of DENSO WAVE INCORPORATED.

Encoder Solution

  • QRCodeEncoderLibrary: a class library project
  • QRCodeEncoderDemo: a Windows Form demo program demonstrating how to encode a string or a byte array into a QR Code image file
  • QRCodeConsoleDemo: a Windows console demo program demonstrating how to encode a text file or a binary file into a QR Code image file

Decoder Solution

  • QRCodeDecoderLibrary: a class library project
  • QRCodeDecoderDemo: a demo program demonstrating how to decode image file containing a QR Code and retrieve the string or byte array. The image file source can be a disk file or a live video camera input. The video camera software is based on Direct Show Library.

The QR Code encoder part of this library is included in the PDF File Writer C# Class Library article.

Installation

The attached source code is made of two Visual Studio solutions. Each solution is made of one library project and demo/test project.

Integrating the code to your application requires the following steps. Install either the QRCodeEncoderLibrary.dll or the QRCodeDecoderLibrary.dll in your development area. Start the Visual Studio C# program and 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 required library. When your application is published, the relevant library file must be included and installed in the same folder as your executable (.exe) file.

Alternatively, you can copy the relevant library's source files into your project.

The relevant "using" statement must be added to all your source files:

C#
using QRCodeEncoderLibrary;
// or
using QRCodeDecoderLibrary;

QR Code

QR Code stands for Quick Response Code. It is a two-dimensional barcode. Visually, it is a square made of small black and white square modules. The square is surrounded by a white quite zone. The QR Code is defined by the international standard ISO/IEC 18004. A free copy of this standard is available here.

The ISO standard document defines the QR Code as “QR Code is a matrix consisting of an array of nominally square modules arranged in an overall square pattern, including a unique finder pattern located at three corners of the symbol and intended to assist in easy location of its position, size and inclination. A wide range of sizes of symbol is provided for together with four levels of error correction. Module dimensions are user-specified to enable symbol production by a wide variety of techniques.”

The ISO standard 18004 is the best source of information for understanding the details of the QR Code. Searching the internet yields many more articles on this subject. Wikipedia article about QR Code can be viewed here.

The QR Code standard is a collection of 40 different squares varying in size. Each square has a version number from 1 to 40. The size of each square varies from 21 by 21 modules (version 1) to 177 by 177 modules (version 40). Each version has 4 more modules per side than the previous version.

C#
Square-Dimension = 21 + 4 * (Version - 1)

Some of the modules are fixed. The most obvious ones are the three-square finders. The remaining modules are divided between data and error correction. There are 4 levels of error correction:

  • L- Low will correct up to 7% errors
  • M- Medium will correct up to 15% errors
  • Q- Quarter will correct up to 25% errors
  • H- High will correct up to 30% errors

Each module in the data area represent one bit. Black module is 1 and white module is 0. The data area can be divided into segments. Each input segment byte array is encoded to data bits in one of three ways numeric, alphanumeric, and byte. Note: The QR Code standard has one more encoding method for Kanji characters. It is not supported by this project.

  • Numeric data: The segment is made only of digits 0–9. Three digits will be converted to 10 bits.
  • Alphanumeric data: The segment is made of digits 0–9, upper case letters A–Z, and nine other characters [space, $ % * + - . / :]. Two alphanumeric characters will be converted to 11 bits.
  • 8-bit byte data. The segment is not converted. There is one to one correspondence between input bits and modules.

To encode a QR Code, you supply the data to be encoded and one of the four error correction codes. The system will calculate the smallest version number required to represent the data.

In addition to data, the QR Code can contains a ECI Assignment Number. The assignment number range is zero to 999999. The number is not part of the QR Code data. It is used for encoding data subject to alternative interpretations of byte values (e.g., alternative character sets).

The program analyzes each segment of data to find the "best" encoding. If you want to reduce the size of the QR Code and you have long strings of digits or alphanumeric data as defined above, then break your input into several strings or byte arrays. Some of these strings must be numeric only or Alphanumeric as defined above. During the decoding process, all resulted string segments will be concatenated together.

When the library decodes an image containing one or more QR Codes, the result will be an array of strings or array of byte arrays. Each array item is one QR Code.

QR Code Encoding

The main class for encoding is QREncoder. It will convert a byte array or a text string into a QR Code image. To create a QR Code image, follow the steps:

Create QREncoder object. Set the two optional parameters. The error correction code and the ECI assignment number. This object is reusable. If you want to create many QR Codes, just reuse this object. There is no initialization or dispose requirement. The optional parameters will retain their value from the last run.

C#
// create QR Code encoder object
QRCodeEncoder Encoder = new();

Set the two optional parameters if required:

C#
// Error correction
// error correction low (7%)
Encoder.ErrorCorrection = ErrorCorrection.L;

// or, error correction medium (15%) The Default
Encoder.ErrorCorrection = ErrorCorrection.M;

// or, error correction quarter (25%)
Encoder.ErrorCorrection = ErrorCorrection.Q;

// or, error correction high (30%)
Encoder.ErrorCorrection = ErrorCorrection.H;

// ECI Assignment Value (default is -1 not used)
// The ECI value is a number in the range of 0 to 999999.
// or -1 if it is not used
Encoder.ECIAssignValue = -1;

Higher error correction percentage gives you better protection against damaged QR Code images. The cost is the increased size of the QR symbol.

Call one of the four Encode methods:

C#
// single text string input
public void Encode(string StringDataSegment);

// multiple text strings input
public void Encode(string[] StringDataSegments);

// single byte array input
public void Encode(byte[] ByteDataSegment);

// multiple byte arrays input
public void Encode(byte[][] ByteDataSegments);

If input data is text string, or array of text strings. The text will be converted to byte array using the following method.

C#
// the encoder converts text string to byte array
// using the conversion method
byte[] ByteArray = Encoding.UTF8.GetBytes(Text);

Effectively, the library software will convert the first and second Encode methods to the third and fourth methods respectively.

The QRCodeEncoderLibrary will scan each incoming data byte array segment to determine the best encoding method. The program will not attempt to break a single segment to minimize the size of the QR Code matrix. You can submit array of segments in such a way as to take advantage of long strings of numeric or alphanumeric data.

The Encode method returns a bool[,] a square matrix of Boolean elements array. The return two-dimensional bool array is available also as a public member QRCodeMatrix of the QREncode class. Each element represents black modules as true and white modules as false. The matrix dimension is given in public member QRCodeDimension. If encoding fails, an exception will be thrown.

The next step is to save the QR Code symbol to a file or, to create a Bitmap. The following example shows how to save the QRCodeMatrix to a PNG image file. Saving the QR Code image to PNG file DOES NOT require the use of Bitmap class and is suitable for net-core and net-standard. The PNG image file is significantly smaller than a PNG file created by Bitmap class in QRSaveBitmapImage.

C#
// save image as png file
// create save PNG image class 
// and load the QR Code matrix 
QRSavePngImage PngImage = new(QRCodeMatrix);

// set the module size in pixels
PngImage.ModuleSize = ModuleSize;

// set the quiet zone in pixels
PngImage.QuietZone = QuietZone;

// save the QR Code PNG image to file name
// or to open file stream
PngImage.SaveQRCodeToPngFile(Dialog.FileName);

Save the QR Code using Bitmap class. Bitmap class allows you to select file format.

C#
// save image as any file format supported by Bitmap class.
// create image class for the QR Code matrix 
QRSaveBitmapImage Image = new(QRCodeMatrix);

// set the module size in pixels
Image.ModuleSize = ModuleSize;

// set the quiet zone in pixels
Image.QuietZone = QuietZone;

// save the QR Code image to file name
// or to open file stream
Image.SaveQRCodeToBitmapFile(Dialog.FileName, ImageFormat);

Create PNG Image File using the CommandLine Class.

The command line arguments are listed below. The arguments set the encoding options.

Command line arguments format:

  • Command Line: exefile [optional arguments] input-file output-file
  • Output file must have .png extension
  • Options format /code:value or -code:value (the : can be =)
  • Error correction level. code=[error|e], value=low|l|medium|m|quarter|q|high|h], default=m
  • Module size. code=[module|m], value=[1-100], default=2
  • Quiet zone. code=[quiet|q], value=[4-400], default=8, min=4*width
  • ECI Assign Value: code=[value|v], value=[0-999999], default is no ECI value.
  • Text file format. code=[text|t] see notes below.
  • Input file is binary unless text file option is specified If input file format is text or t, the string will be encoded to byte array.

QR Code Encoder Demo

QR Code Encoder Demo is a test program showing how to encode a QR Code and save it as an image file.

  • Select error correction level.
  • Set ECI assignment value or leave it blank.
  • Enter the text into the data box. You can use the pipe | character to break the string into segments of numeric, alphanumeric, and general text.
  • Press Encode. The QR Code will be displayed.
  • The QRCodeMatrix will be created.
  • Either press Save Image button or the Copy to Clipbord button.
  • If you press the Copy to Clipboard, the QR image with module width of 2 and quiet zone of 8 will be loaded to the clipboard.
  • If you press the Save Image, the Save QR Code Image dialog box will be displayed.
  • Set module size.
  • Set quiet zone.
  • Set Image Format (not required for compressed PNG).
  • Press on one of the four Save buttons.
  • Press Save Compressed PNG to save the image in PNG format not using Bitmap.
  • or, Press Bitmap Image.
  • or, Press Save Special. The save special screen will be displayed. This option is made for creating image files for decoding testing. The Save QR Code Image screen allows you to save the QR Code image over a brush or image background. You can rotate the QR Code or display it as if it were taken by a camera to yield perspective picture. You can add circular spots at random over the image.
  • or, Press Copy to Clipboard. This button will create an image with the specified module size and quiet zone size.

QR Code Encoder Demo

QR Code Encoder Demo

QR Code Save Dialog

QR Code Save Dialog

Save QR Code Image

Save Special QR Code Image

QR Code Decoding

The QRDecoder converts image files or Bitmaps containing QR Code symbols into an array of QRCodeResult. Each result item contains the QR Code data byte array and ECI Assignment Value. To decode an image file containing one or more QR Code images, follow these steps.

Create QRDecoder object. This object is reusable. If you want to decode a few images, just reuse this object. There is no initialization or dispose requirement.

C#
// create QR Code decoder object
QRDecoder Decoder = new QRDecoder();

// call image decoder method with file name
QRCodeResult[] ResultArray = Decoder.ImageDecoder(FileName)

Each QRCode symbol decoded successfully will return a QRCodeResult element. In most cases, it will be an array of one element. The result is defined below. The DataArray represent the contents of the QR Code. However, in some cases, you might be interested in the other members. If the returned value is null, no QR Code was detected.

C#
// QR Code result 
public class QRCodeResult
    {
    // QR Code Data array
    public byte[] DataArray;

    // ECI Assignment Value
    public int ECIAssignValue;

    // the next members are for information only
    // QR Code matrix version
    public int QRCodeVersion;

    // QR Code matrix dimension in bits
    public int QRCodeDimension;

    // QR Code error correction code (L, M, Q, H)
    public ErrorCorrection ErrorCorrection;
    }

To convert the data byte array QRCodeResult.DataArray to a text string use:

C#
// convert binary result to text string
string TextResult = QRCode.ByteArrayToStr(ResultArray[Index].DataArray);

The ByteArrayToStr method converts byte array into string in the following way:

C#
// The QRDecoder converts byte array to text string 
// using this conversion
public static string ByteArrayToStr(byte[] DataArray)
	{
	Decoder = Encoding.UTF8.GetDecoder();
	int CharCount = Decoder.GetCharCount(DataArray, 0, DataArray.Length);
	char[] CharArray = new char[CharCount];
	Decoder.GetChars(DataArray, 0, DataArray.Length, CharArray, 0);
	return new string(CharArray);
	}

For example, the image below is of two QR Codes one within the other. The big one data is: Big QR Code, the small one data is: Small QR Code. The big one has error correction set to High. The program will find both QR Codes and recover the missing area of the big one using error correction to get the correct content.

QR Code Example

QR Code 1
Big QR Code
QR Code 2
Small QR Code

Another example of three QR Codes. The decoder finds 9 finders in the picture. All possible 3 out of 9 finders are tested. The result is three groups of three finders test for valid QR Code structure. The result is given below in the picture.

Triple QR Codes

QR Code 1
Top left corner
QR Code 2
Top right corner
QR Code 3
Bottom left corner

QR Code Decoder Demo

QR Code Decoder Demo is a test program showing how to scan an image file or a video image for QR Codes. Next, it will show how to convert the decoded data into a text string. The video decoder is a test/demo application that will use the first found web camera in your system. A demo program combining QR Code decoder and video camera image capture. The video camera software is based on the Direct Show Library.

QR Code Decoder Demo

  • Click on Image File button or Video Camera button.
  • For image file, an open file dialog will be displayed.
  • The image will be displayed.
  • For video, place your QR code in front of the camera.
  • If decoding is successful, the Decoded data area will display the result.
  • If decoding is not successful, the Decoded data area will be blank.
  • If the image contains more than one QR Code, the Decoded data will display the results of all QR Codes.

For your information, the video capture is using some of the source modules of Camera_Net project published at CodeProject.com and at Github This project is based on DirectShowLib.. Please note the DirectShowLib in this project is a modified subset of the original source modules.

Please note, I have only tested this application on my own video camera. My camera is Logitech HD Webcam C615. I am using frame size of 640 by 480 pixels.

The program sets the camera software to display the video stream in a preview area on the screen. The scanning is 5 frames per seconds. Each frame is captured and tested for a QR Code. Once a QR Code is found, the result is displayed at the Decoded data text box. If the decoded data is a URI, the Go To URI button is enabled, and you can display this URI on your default web browser.

For video decoding to be successful, each QR Code module must be represented by a few camera pixels. For example, 4 by 4 or more pixels. The QR Code must be reasonably sharp, flat, and parallel to the camera. The picture below illustrates the power of the software to transform the image to a square with the finder symbols at their correct positions.

QR Code Video Decoder

History

  • 30th June, 2018: Version 1.0.0 Original version
  • 20th July, 2018: Version 1.1.0 DirectShowLib consolidation
  • 15th May, 2019: Version 2.0.0 The software was divided into two solutions. Encoder solution and Decoder solution. The encode solution is a multi-target solution. It will produce net462 netstandardapp2.0 libraries.
  • 22nd July, 2019: Version 2.1.0 ECI Assignment Value support was added.
  • 1st March: 2022: Version 3.0.0 upgrade to VS 2022 and .NET 6.0.
  • 8 March 2022 Version 3.1.0 Fix for video decoder. Protect against unplugging the camera while using the demo. No change to encoder.
  • 17 March 2022 Version 3.1.0 Encoder demo program. Add copy to clipboard feature.

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

 
GeneralRe: Warning Pin
YDaoust21-Mar-22 0:13
YDaoust21-Mar-22 0:13 
GeneralMy vote of 5 Pin
tugrulGtx19-Mar-22 4:45
tugrulGtx19-Mar-22 4:45 
GeneralRe: My vote of 5 Pin
Uzi Granot19-Mar-22 4:48
Uzi Granot19-Mar-22 4:48 
QuestionClipboard Pin
cbruun16-Mar-22 23:56
cbruun16-Mar-22 23:56 
AnswerRe: Clipboard Pin
Uzi Granot17-Mar-22 2:29
Uzi Granot17-Mar-22 2:29 
AnswerRe: Clipboard Pin
Uzi Granot17-Mar-22 14:33
Uzi Granot17-Mar-22 14:33 
GeneralRe: Clipboard Pin
cbruun18-Mar-22 1:47
cbruun18-Mar-22 1:47 
AnswerRe: Clipboard Pin
Uzi Granot18-Mar-22 1:52
Uzi Granot18-Mar-22 1:52 
To find the answer, click on "A free copy of the standard is available here" in the QR Code section. Go to page 24-32. The capacity is a function of the size, the error correction and the compression used.
GeneralRe: Clipboard Pin
cbruun18-Mar-22 2:34
cbruun18-Mar-22 2:34 
GeneralRe: Clipboard Pin
Uzi Granot18-Mar-22 4:01
Uzi Granot18-Mar-22 4:01 
GeneralRe: Clipboard Pin
cbruun18-Mar-22 2:34
cbruun18-Mar-22 2:34 
QuestionLogo inside QR Pin
Buttibis16-Mar-22 20:33
Buttibis16-Mar-22 20:33 
AnswerRe: Logo inside QR Pin
Uzi Granot17-Mar-22 5:43
Uzi Granot17-Mar-22 5:43 
GeneralRe: Logo inside QR Pin
Buttibis17-Mar-22 5:58
Buttibis17-Mar-22 5:58 
QuestionMy Vote of 5 Pin
Member 1030465010-Mar-22 0:10
Member 1030465010-Mar-22 0:10 
AnswerRe: My Vote of 5 Pin
Uzi Granot10-Mar-22 0:58
Uzi Granot10-Mar-22 0:58 
GeneralMy vote of 5 Pin
Ccasalicchio9-Mar-22 5:28
professionalCcasalicchio9-Mar-22 5:28 
GeneralRe: My vote of 5 Pin
Uzi Granot9-Mar-22 5:59
Uzi Granot9-Mar-22 5:59 
GeneralMy vote of 5 Pin
Moshe Ventura 20218-Mar-22 6:58
Moshe Ventura 20218-Mar-22 6:58 
GeneralRe: My vote of 5 Pin
Uzi Granot8-Mar-22 7:19
Uzi Granot8-Mar-22 7:19 
QuestionCannot get the decoder to work correctly! Pin
Member 155588617-Mar-22 22:14
Member 155588617-Mar-22 22:14 
AnswerRe: Cannot get the decoder to work correctly! Pin
Uzi Granot8-Mar-22 2:58
Uzi Granot8-Mar-22 2:58 
GeneralRe: Cannot get the decoder to work correctly! Pin
Member 155588618-Mar-22 3:10
Member 155588618-Mar-22 3:10 
GeneralRe: Cannot get the decoder to work correctly! Pin
Uzi Granot8-Mar-22 3:23
Uzi Granot8-Mar-22 3:23 
GeneralRe: Cannot get the decoder to work correctly! Pin
Member 155588618-Mar-22 3:29
Member 155588618-Mar-22 3:29 

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.