ZXing Barcode Scanner in .NET: ZXing.NET vs IronBarcode
If you have searched for a "ZXing barcode scanner" in C#, you have probably landed on ZXing.NET, the community port of the Java ZXing project (pronounced "zebra crossing"). It reads and writes a broad set of 1D and 2D symbologies, and it has been a reference for barcode handling for well over a decade. This comparison puts it next to IronBarcode and lets the code show where each one fits.
Full disclosure: we build IronBarcode at Iron Software, one of the two libraries here. ZXing.NET is free and genuinely capable; we'll flag where it's the better pick and let the code speak.
Here is the short version. ZXing.NET is free, open source, and mature, and for clean, standard barcodes it does exactly the job. The tradeoff is that you handle the imaging glue and any preprocessing yourself, and the library follows a community release cadence. IronBarcode is commercial, but it bundles the imaging stack, image correction, and PDF reading, so noisy or rotated input needs less code from you. Pick by use case, not by logo.
A minimal ZXing.NET scan
ZXing.NET ships on NuGet. The core package carries the format definitions and decoding logic but deliberately leaves out an imaging dependency, so you pair it with a binding. On Windows, ZXing.Windows.Compatibility adds the System.Drawing glue.
Install-Package ZXing.Net
using System;
using System.Drawing;
using ZXing;
using ZXing.Windows.Compatibility;
var barcodeReader = new BarcodeReader();
var scanResult = barcodeReader.Decode((Bitmap)Image.FromFile("barcode.png"));
Console.WriteLine(scanResult?.Text); // null-conditional: Decode returns null on no match
Decode returns a single Result, or null when nothing is found, which is why the null-conditional ?.Text matters. For a clean image of a standard symbology, we find that is all you need, and it works well.
💡 If you want to spend more CPU recovering a marginal scan, set Options = new ZXing.Common.DecodingOptions { TryHarder = true } on the reader.
What ZXing.NET covers
ZXing.NET inherits the broad symbology coverage of the Java project, which is the main reason developers reach for it:
- 1D / linear: UPC-A, UPC-E, EAN-8, EAN-13, Code 39, Code 93, Code 128, ITF, Codabar, MSI, RSS-14
- 2D / matrix: QR Code, Data Matrix, Aztec, PDF-417
Both reading and writing are supported, so the same package generates a QR code or a Code 128 as well as decoding one. If you know which formats you expect, restrict the reader to them, since it cuts false positives and speeds up the scan when the decoder stops probing symbologies you will never receive.
✅ For a project that scans clean retail barcodes or generates QR codes, this is a solid, zero-cost foundation, and we would point you straight at it.
Where the friction shows up
In our experience the rough edges are rarely in the core decoding; they show up around a real integration.
Imaging setup
Because the core package has no image dependency, decoding a file on modern .NET means also installing a binding such as ZXing.Net.Bindings.SkiaSharp, ZXing.Net.Bindings.ImageSharp, or ZXing.Windows.Compatibility. You also work around System.Drawing.Common being Windows-only on newer .NET, which is why cross-platform teams often standardize on SkiaSharp or ImageSharp.
Image correction
ZXing.NET handles grayscale, binarization, and a TryHarder mode, but it offers fewer built-in helpers for rotation, skew, low resolution, or noisy scanner output. When a source image needs cleanup, that preprocessing is your job through whichever imaging library you bound to.
Release cadence
⚠️ ZXing.NET is community-maintained and tracks an upstream Java project, so releases arrive on a community schedule rather than a commercial timeline. For many teams that is fine; for some with stricter support needs, it is a factor to weigh. None of this makes ZXing.NET a poor choice. It describes where the work lives.
The same scan with IronBarcode
IronBarcode is the commercial .NET library we build: it packages the imaging stack, correction, and document handling in one namespace. There is one package to install and no per-platform binding to pick.
Install-Package BarCode
using IronBarCode;
using System;
var scanResults = BarcodeReader.Read("barcode.png");
foreach (var barcode in scanResults)
Console.WriteLine(barcode.Text);
You can install IronBarcode from NuGet and run that in about five minutes. Read returns a collection rather than a single result, so an image holding several barcodes comes back in one call. For the clean single-barcode case, we think the two libraries are close enough that cost and license model should decide it, and ZXing.NET being free is a real advantage there.
The gap widens on imperfect input. Where you would hand-write rotation and noise handling for ZXing.NET, we expose it through reader options:
using IronBarCode;
using System;
var readerOptions = new BarcodeReaderOptions
{
ExpectMultipleBarcodes = true,
Speed = ReadingSpeed.Detailed, // spend more CPU on messy input
ImageFilters = new ImageFilterCollection
{
new SharpenFilter(),
new ContrastFilter()
}
};
var skewedResults = BarcodeReader.Read("skewed-scan.png", readerOptions);
foreach (var barcode in skewedResults)
Console.WriteLine($"{barcode.BarcodeType}: {barcode.Text}");
The Detailed speed setting and the filter chain are what you reach for on skewed, low-contrast, or noisy scans. IronBarcode can also read straight from a PDF and batch across pages without you rasterizing each one first. That is the practical difference: less glue code for messy or multi-page input, at the cost of a commercial license.
How they compare
| Factor | ZXing.NET | IronBarcode |
|---|---|---|
| Read / write | ✅ Both | ✅ Both |
| Symbologies | 1D (UPC, EAN, Code 39/93/128, ITF, Codabar, MSI) and 2D (QR, Data Matrix, Aztec, PDF-417) | Same broad 1D and 2D set |
| Image preprocessing | Manual, through bound imaging library | Built-in sharpen, contrast, rotation, noise correction |
| Imaging dependency | Separate binding package required | Self-contained |
| Read from PDF / multi-page | Manual rasterization first | ✅ Direct, batched |
| .NET targets | .NET Standard / Core / Framework (+ binding) | .NET Standard / Core 2.0+, Windows, Linux, macOS, Azure |
| License | Apache 2.0, free, open source | Commercial, paid |
| Maintenance | Community cadence, tracks Java upstream | Commercial release cadence and support |
So which one?
There is no single winner here, and we would distrust a comparison that claimed one.
- ✅ Pick ZXing.NET if you want free, open-source, full-source-access barcode handling, your images are clean and standard, and you are comfortable wiring an imaging binding and any preprocessing yourself. For a great many projects, that is the right call.
- ✅ Pick IronBarcode if your input is skewed, noisy, rotated, or arrives as PDFs, you are batch-reading at volume, and a single-package install with built-in correction and commercial support is worth a license fee. The IronBarcode barcode reading tutorial covers PDF input and the filter options shown above.
The fairest test is your own data. Run the same set of representative images through both and compare what decodes and how much code each one took.
Which barcode library are you running in production, and what tipped the decision? We would genuinely like to hear which one held up on your worst scans in the comments.
If your worst scans are the problem, you can put IronBarcode against your own images with the free trial.
ZXing and ZXing.NET are trademarks of their respective owners; this comparison reflects publicly available information at the time of writing.
Top comments (0)