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.
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:
using QRCodeEncoderLibrary;
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.
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 string
s 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.
QRCodeEncoder Encoder = new();
Set the two optional parameters if required:
Encoder.ErrorCorrection = ErrorCorrection.L;
Encoder.ErrorCorrection = ErrorCorrection.M;
Encoder.ErrorCorrection = ErrorCorrection.Q;
Encoder.ErrorCorrection = ErrorCorrection.H;
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:
public void Encode(string StringDataSegment);
public void Encode(string[] StringDataSegments);
public void Encode(byte[] ByteDataSegment);
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.
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
.
QRSavePngImage PngImage = new(QRCodeMatrix);
PngImage.ModuleSize = ModuleSize;
PngImage.QuietZone = QuietZone;
PngImage.SaveQRCodeToPngFile(Dialog.FileName);
Save the QR Code using Bitmap
class. Bitmap
class allows you to select file format.
QRSaveBitmapImage Image = new(QRCodeMatrix);
Image.ModuleSize = ModuleSize;
Image.QuietZone = QuietZone;
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 Save Dialog
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.
QRDecoder Decoder = new QRDecoder();
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.
public class QRCodeResult
{
public byte[] DataArray;
public int ECIAssignValue;
public int QRCodeVersion;
public int QRCodeDimension;
public ErrorCorrection ErrorCorrection;
}
To convert the data byte array QRCodeResult.DataArray
to a text string
use:
string TextResult = QRCode.ByteArrayToStr(ResultArray[Index].DataArray);
The ByteArrayToStr
method converts byte array into string
in the following way:
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 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.
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.
- 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.
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.