Barcode generators are essential tools in various scenarios. A typical use case is testing barcode reader and scanner SDKs. In this tutorial, we'll build a Windows Forms application that can both generate and read barcodes using two popular .NET Barcode SDKs: ZXing.NET and Dynamsoft Barcode Reader. ZXing.NET offers both barcode generation and decoding capabilities, while Dynamsoft Barcode Reader provides more robust and accurate recognition. This application allows you to compare the two SDKs side-by-side and evaluate their performance.
Demo: .NET Barcode Generator & Reader
Prerequisites
- Visual Studio 2022 with .NET 8.0
- 30-day trial license for Dynamsoft Barcode Reader.
Step 1: Create the WinForms Project
- Open Visual Studio and create a new .NET Windows Forms App project.
- Name the project "BarcodeGenerator" and set the target framework to .NET 8.0.
-
Add the required NuGet packages:
Install-Package ZXing.Net Install-Package ZXing.Net.Bindings.Windows.Compatibility Install-Package Dynamsoft.DotNet.BarcodeReader.Bundle
Note:
- Dynamsoft Barcode Reader is now a module of the Dynamsoft Capture Vision SDK, and they share the same API structure.
- ZXing.Net requires ZXing.Net.Bindings.Windows.Compatibility to function properly with
Bitmap
and other Windows-specific types.
Step 2: Design the UI
The application uses a tabbed interface with three main sections:
- Generate Tab: For creating barcodes.
- Read Tab: For decoding barcodes from generated or uploaded images.
- Settings Tab: To switch between SDKs.
Here's the basic form initialization code:
public Form1() { InitializeComponent(); MinimumSize = new Size(900, 900); Text = "Barcode Generator and Reader (ZXing.NET & Dynamsoft Barcode Reader)"; Width = 800; Height = 600; tabControl = new TabControl { Dock = DockStyle.Fill }; generateTab = new TabPage("Generate"); readTab = new TabPage("Read"); settingsTab = new TabPage("Settings"); InitGenerateTab(); InitReadTab(); InitSettingsTab(); InitSDK(); tabControl.TabPages.Add(generateTab); tabControl.TabPages.Add(readTab); tabControl.TabPages.Add(settingsTab); Controls.Add(tabControl); }
Step 3: Implement Barcode Generation
We'll use ZXing.NET to generate barcodes. The main UI components on the Generate tab include:
- A text input field for the barcode content
- A format selector dropdown with all supported formats
- A generate button to create the barcode
- A save button to save the generated barcode image
- A picture box to preview the barcode
private void InitGenerateTab() { Label inputLabel = new Label { Text = "Text to Encode:", Top = 20, Left = 20 }; inputTextBox = new TextBox { Top = 45, Left = 20, Width = 300 }; Label formatLabel = new Label { Text = "Format:", Top = 80, Left = 20 }; formatComboBox = new ComboBox { Top = 105, Left = 20, Width = 200 }; formatComboBox.Items.AddRange(Enum.GetNames(typeof(BarcodeFormat))); formatComboBox.SelectedIndex = 0; generateButton = new Button { Text = "Generate", Top = 145, Left = 20 }; generateButton.Click += GenerateButton_Click; saveButton = new Button { Text = "Save", Top = 145, Left = 120 }; saveButton.Click += SaveButton_Click; barcodePictureBox = new PictureBox { Top = 200, Left = 20, Width = 600, Height = 400, BorderStyle = BorderStyle.FixedSingle, SizeMode = PictureBoxSizeMode.Zoom, Anchor = AnchorStyles.Top | AnchorStyles.Left }; generateTab.Controls.AddRange(new Control[] { inputLabel, inputTextBox, formatLabel, formatComboBox, generateButton, saveButton, barcodePictureBox }); }
Here's the barcode generation logic:
private void GenerateButton_Click(object sender, EventArgs e) { if (string.IsNullOrEmpty(inputTextBox.Text)) { inputTextBox.Text = GenerateRandomContent((BarcodeFormat)Enum.Parse(typeof(BarcodeFormat), formatComboBox.SelectedItem.ToString())); } var writer = new BarcodeWriterPixelData { Format = (BarcodeFormat)Enum.Parse(typeof(BarcodeFormat), formatComboBox.SelectedItem.ToString()), Options = new EncodingOptions { Height = 400, Width = 450, Margin = 10 } }; PixelData pixelData; try { pixelData = writer.Write(inputTextBox.Text); } catch (Exception ex) { MessageBox.Show($"Error generating barcode: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } var bitmap = new Bitmap(pixelData.Width, pixelData.Height, PixelFormat.Format32bppRgb); var bitmapData = bitmap.LockBits( new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.WriteOnly, bitmap.PixelFormat); try { System.Runtime.InteropServices.Marshal.Copy( pixelData.Pixels, 0, bitmapData.Scan0, pixelData.Pixels.Length); } finally { bitmap.UnlockBits(bitmapData); } barcodePictureBox.Image = bitmap; inputImageBox.Image = bitmap; }
If the input text is empty, randomly generate a content for the barcode:
private string GenerateRandomContent(BarcodeFormat format) { Random rnd = new Random(); switch (format) { case BarcodeFormat.EAN_13: int part1 = rnd.Next(10, 99); int part2 = rnd.Next(100000000, 999999999); int part3 = rnd.Next(0, 9); return $"{part1}{part2}{part3}"; case BarcodeFormat.EAN_8: return rnd.Next(1000000, 9999999).ToString(); case BarcodeFormat.CODE_39: case BarcodeFormat.CODE_128: case BarcodeFormat.CODABAR: return "ZX" + rnd.Next(100000, 999999); case BarcodeFormat.QR_CODE: return "https://www.dynamsoft.com?id=" + rnd.Next(1000, 9999); case BarcodeFormat.UPC_A: return rnd.NextInt64(10000000000L, 99999999999L).ToString(); case BarcodeFormat.ITF: return rnd.Next(100000000, 999999999).ToString(); default: return "TEST" + rnd.Next(1000, 9999); } }
Click the save button to save the generated barcode image as JPEG, PNG, or BMP.
private void SaveButton_Click(object sender, EventArgs e) { if (barcodePictureBox.Image == null) { MessageBox.Show("Please generate a barcode first.", "No Image", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } using SaveFileDialog dialog = new SaveFileDialog { Filter = "PNG Image|*.png|JPEG Image|*.jpg|Bitmap Image|*.bmp", Title = "Save Barcode Image", FileName = "barcode" }; if (dialog.ShowDialog() == DialogResult.OK) { var format = ImageFormat.Png; switch (Path.GetExtension(dialog.FileName).ToLower()) { case ".jpg": format = ImageFormat.Jpeg; break; case ".bmp": format = ImageFormat.Bmp; break; } barcodePictureBox.Image.Save(dialog.FileName, format); MessageBox.Show("Image saved successfully.", "Saved", MessageBoxButtons.OK, MessageBoxIcon.Information); } }
Step 4: Implement Barcode Reading
The Read tab allows users to upload and decode barcode images. The UI includes:
- A button to upload an image
- A button to decode the image
- A picture box to display the uploaded or generated image
- A text box to show the barcode decoding results
private void InitReadTab() { uploadImageButton = new Button { Text = "Upload Image", Top = 20, Left = 20, Width = 120 }; uploadImageButton.Click += UploadImageButton_Click; decodeButton = new Button { Text = "Decode", Top = 20, Left = 160, Width = 100 }; decodeButton.Click += DecodeButton_Click; inputImageBox = new PictureBox { Top = 60, Left = 20, Width = 600, Height = 400, BorderStyle = BorderStyle.FixedSingle, SizeMode = PictureBoxSizeMode.Zoom, Anchor = AnchorStyles.Top | AnchorStyles.Left }; resultTextBox = new TextBox { Top = inputImageBox.Bottom + 20, Left = 20, Width = 600, Height = 100, Multiline = true, Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right, ScrollBars = ScrollBars.Vertical }; readTab.Controls.AddRange(new Control[] { uploadImageButton, decodeButton, inputImageBox, resultTextBox }); }
Decoding Barcode Images
The application supports decoding using either ZXing.NET or Dynamsoft Barcode Reader, depending on the SDK selected from the Settings tab.
-
Initialize the Dynamsoft Barcode Reader SDK with a license key:
private void InitSDK() { string errorMsg; int errorCode = LicenseManager.InitLicense("LICENSE-KEY", out errorMsg); if (errorCode != (int)EnumErrorCode.EC_OK) Console.WriteLine("License initialization error: " + errorMsg); }
-
Trigger the decoding process with different .NET Barcode SDKs:
private void DecodeButton_Click(object sender, EventArgs e) { if (inputImageBox.Image is not Bitmap bitmap) return; string selectedSdk = sdkSelectorComboBox.SelectedItem.ToString(); string content = ""; if (selectedSdk == "ZXing") { content += "ZXing Barcode Reader\r\n\r\n"; var reader = new BarcodeReader(); try { var result = reader.DecodeMultiple(bitmap); content += "Total Barcodes Found: " + (result?.Length ?? 0) + Environment.NewLine; foreach (var item in result) { content += " Type: " + item.BarcodeFormat + ", " + "Content: " + item.Text + Environment.NewLine; } } catch (Exception ex) { MessageBox.Show($"Error decoding barcode: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } } else if (selectedSdk == "Dynamsoft Barcode Reader") { content += "Dynamsoft Barcode Reader\r\n\r\n"; CaptureVisionRouter cvr = new CaptureVisionRouter(); byte[] bytes; int width; int height; int stride; PixelFormat pixelFormat; GetBitmapData(bitmap, out bytes, out width, out height, out stride, out pixelFormat); EnumImagePixelFormat format = EnumImagePixelFormat.IPF_RGB_888; switch (pixelFormat) { case PixelFormat.Format24bppRgb: format = EnumImagePixelFormat.IPF_RGB_888; break; case PixelFormat.Format32bppArgb: case PixelFormat.Format32bppRgb: format = EnumImagePixelFormat.IPF_ARGB_8888; break; default: MessageBox.Show("Unsupported pixel format."); return; } ImageData data = new ImageData(bytes, width, height, stride, format); CapturedResult result = cvr.Capture(data, PresetTemplate.PT_READ_BARCODES); if (result != null && result.GetErrorCode() == 0) { DecodedBarcodesResult barcodesResult = result.GetDecodedBarcodesResult(); if (barcodesResult != null) { BarcodeResultItem[] items = barcodesResult.GetItems(); content += "Total Barcodes Found: " + items.Length + Environment.NewLine; foreach (BarcodeResultItem barcodeItem in items) { content += " Type: " + barcodeItem.GetFormatString() + ", " + "Content: " + barcodeItem.GetText() + Environment.NewLine; } } } } resultTextBox.Text = content != "" ? content : "No barcode found."; }
Step 5: Implement the Settings Tab
The Settings tab allows the user to choose between the two barcode SDKs:
private void InitSettingsTab() { Label sdkLabel = new Label { Text = "Barcode SDK", Top = 20, Left = 20 }; sdkSelectorComboBox = new ComboBox { Top = 45, Left = 20, Width = 200, DropDownStyle = ComboBoxStyle.DropDownList }; sdkSelectorComboBox.Items.AddRange(new string[] { "ZXing", "Dynamsoft Barcode Reader" }); sdkSelectorComboBox.SelectedIndex = 0; settingsTab.Controls.AddRange(new Control[] { sdkLabel, sdkSelectorComboBox }); }
Step 6: Run the .NET Barcode Generator & Reader Application
- Press F5 in Visual Studio to build and launch the application.
-
Try generating different barcode formats.
-
Test barcode decoding using a .NET Barcode SDK.
Source Code
https://github.com/yushulx/dotnet-barcode-qr-code-sdk/tree/main/example/official/BarcodeGenerator
Top comments (0)