Skip to footer content
USING IRONQR

QR Code .NET Core: Read and Generate QR Codes in C#

When building web or enterprise applications on .NET Core, QR code support -- for inventory tracking, payment flows, or two-factor authentication -- is a frequent requirement. Rather than spending development cycles on low-level encoding algorithms, you can reach for a dedicated library that handles the full workflow. IronQR provides a complete QR code solution for .NET, covering everything from basic generation to ML-powered reading and advanced error correction.

Ready to try it for yourself? Start your free trial today and see how quickly you can add QR functionality to your project.

NuGet Install with NuGet

PM >  Install-Package IronQR

Check out IronQR on NuGet for quick installation. With over 10 million downloads, it’s transforming PDF development with C#. You can also download the DLL.

How Do You Install the QR Code Library?

Installing IronQR via NuGet takes seconds. Open Visual Studio, go to Tools > NuGet Package Manager > Manage NuGet Packages for Solution, search for IronQR, and click Install. The package has minimal dependencies and targets Windows, macOS, and Linux out of the box.

Install-Package IronQR

IronQR targets .NET Core 6, 7, 8, 9, and 10, as well as .NET Framework 4.6.2 and later. For cross-platform projects, a SkiaSharp integration handles image processing on non-Windows runtimes. The library works with ASP.NET Core web applications, console apps, and desktop solutions without additional runtime configuration. Once installed, all necessary extension methods and types are available immediately.

How Do You Read a Basic QR Code from an Image?

Reading QR code data from image files requires only a few lines of code. The QrReader class uses an advanced machine learning model that evaluates image quality and selects the correct segment mode automatically, giving you accurate results even when the input image is not ideal.

using IronQr;
using IronSoftware.Drawing;

// Load image containing QR code
var inputBmp = AnyBitmap.FromFile("qr-sample.png");
// Create QrImageInput from the bitmap
QrImageInput imageInput = new QrImageInput(inputBmp);
// Initialize QR Reader with ML model
QrReader reader = new QrReader();
// Read and decode all QR codes in the image
IEnumerable<QrResult> results = reader.Read(imageInput);
// Output decoded text strings
foreach (var qrCode in results)
{
    Console.WriteLine($"QR Code Value: {qrCode.Value}");
    Console.WriteLine($"URL: {qrCode.Url}");
}
using IronQr;
using IronSoftware.Drawing;

// Load image containing QR code
var inputBmp = AnyBitmap.FromFile("qr-sample.png");
// Create QrImageInput from the bitmap
QrImageInput imageInput = new QrImageInput(inputBmp);
// Initialize QR Reader with ML model
QrReader reader = new QrReader();
// Read and decode all QR codes in the image
IEnumerable<QrResult> results = reader.Read(imageInput);
// Output decoded text strings
foreach (var qrCode in results)
{
    Console.WriteLine($"QR Code Value: {qrCode.Value}");
    Console.WriteLine($"URL: {qrCode.Url}");
}
$vbLabelText   $csharpLabel

Input QR Code

QR Code Generator .NET Core: Read and Generate QR Codes with Just a Few Lines of Code: Image 1 - Input QR Code

Output

QR Code Generator .NET Core: Read and Generate QR Codes with Just a Few Lines of Code: Image 2 - Example QR Code scan output

The QrReader.Read() method processes the QrImageInput and returns an IEnumerable<QrResult>, where each result carries the decoded text, the URL if one was encoded, and the spatial position of the QR symbol in the image. The library accepts byte arrays, file paths, and AnyBitmap objects, giving you flexibility for any project architecture -- whether you are reading from disk, a database, or a live camera feed.

The ML model underpinning the reader distinguishes IronQR from purely algorithmic libraries. It handles real-world imperfections such as motion blur, partial occlusion, and uneven lighting without requiring manual preprocessing or threshold tuning.

How Do You Extract Advanced QR Code Data?

Beyond basic value decoding, IronQR exposes coordinates, raw data segments, and module-level information from each scanned symbol. This is essential for document processing workflows where you need to know exactly where a QR code appeared on the page, or for applications that must handle multiple codes in a single image.

using IronQr;
using IronSoftware.Drawing;

var inputBmp = AnyBitmap.FromFile("document-with-qr.png");
QrImageInput imageInput = new QrImageInput(inputBmp);
QrReader reader = new QrReader();
IEnumerable<QrResult> results = reader.Read(imageInput);
foreach (var qrCode in results)
{
    // Access decoded value
    Console.WriteLine($"Data: {qrCode.Value}");
    // Get corner coordinate positions
    foreach (PointF point in qrCode.Points)
    {
        Console.WriteLine($"Position: {point.X}, {point.Y}");
    }
}
using IronQr;
using IronSoftware.Drawing;

var inputBmp = AnyBitmap.FromFile("document-with-qr.png");
QrImageInput imageInput = new QrImageInput(inputBmp);
QrReader reader = new QrReader();
IEnumerable<QrResult> results = reader.Read(imageInput);
foreach (var qrCode in results)
{
    // Access decoded value
    Console.WriteLine($"Data: {qrCode.Value}");
    // Get corner coordinate positions
    foreach (PointF point in qrCode.Points)
    {
        Console.WriteLine($"Position: {point.X}, {point.Y}");
    }
}
$vbLabelText   $csharpLabel

Input QR

QR Code Generator .NET Core: Read and Generate QR Codes with Just a Few Lines of Code: Image 3 - Input QR code

Advanced QR Read Results

QR Code Generator .NET Core: Read and Generate QR Codes with Just a Few Lines of Code: Image 4 - Results for advanced QR data extraction

The QrResult.Points collection contains the four corner coordinates of the detected QR symbol in pixel space. Your application can use these to overlay bounding boxes on document images, crop the QR region for further processing, or pass the location data to a downstream system that maps physical coordinates to logical document positions.

IronQR processes codes that contain custom embedded logos, damaged modules, or low-resolution input through the same ML pipeline. The library does not require separate preprocessing steps -- detection and decoding happen in a single Read() call.

How Do Error Correction Levels Affect QR Code Quality?

Error correction is the mechanism that allows a QR scanner to recover the original data even when part of the code is obscured, printed poorly, or physically damaged. The QR Code standard defines four levels -- Low (L), Medium (M), Quartile (Q), and High (H) -- each trading storage capacity for damage tolerance.

Level Recovery Capacity Best Use
L ~7% Clean digital displays, maximum data density
M ~15% General print applications
Q ~25% Industrial labels, moderate wear expected
H ~30% Logos embedded, outdoor or high-wear surfaces

When generating QR codes, specifying a higher error correction level ensures the output holds up under real scanning conditions:

using IronQr;
using IronSoftware.Drawing;

// Configure QR options with high error correction
var qrOptions = new QrOptions(QrErrorCorrectionLevel.High, 20);
// Generate a QR code with specified error correction
QrCode myQr = QrWriter.Write("https://ironsoftware.com", qrOptions);
// Save as PNG image
AnyBitmap qrImage = myQr.Save();
qrImage.SaveAs("high-error-correction-qr.png");
using IronQr;
using IronSoftware.Drawing;

// Configure QR options with high error correction
var qrOptions = new QrOptions(QrErrorCorrectionLevel.High, 20);
// Generate a QR code with specified error correction
QrCode myQr = QrWriter.Write("https://ironsoftware.com", qrOptions);
// Save as PNG image
AnyBitmap qrImage = myQr.Save();
qrImage.SaveAs("high-error-correction-qr.png");
$vbLabelText   $csharpLabel

Output

QR Code Generator .NET Core: Read and Generate QR Codes with Just a Few Lines of Code: Image 5 - Generated QR Code with high error correction level

The QrOptions constructor accepts the error correction level and a maximum version number. Version 40 codes store up to 7,089 numeric characters, while version 1 codes hold only 41. Setting a lower maximum version constrains the output size, which is useful when you need consistent physical dimensions across a batch. The higher the error correction level, the more modules are reserved for redundancy, reducing the net data capacity at any given version.

The fault tolerance feature in IronQR reads alongside this property -- when reading codes generated at higher correction levels, the library recovers data from codes that would fail entirely with a purely algorithmic decoder.

How Do You Generate QR Codes with International Characters?

IronQR supports the full range of QR encoding modes: numeric, alphanumeric, byte, and Kanji. For Japanese text and other Unicode content, the library selects the most space-efficient encoding automatically:

using IronQr;
using IronSoftware.Drawing;

// Generate QR that encodes Japanese Unicode text
QrCode japaneseQr = QrWriter.Write("こんにちは世界");
// The library selects Kanji mode automatically
AnyBitmap qrImage = japaneseQr.Save();
qrImage.SaveAs("japanese-qr.png");
using IronQr;
using IronSoftware.Drawing;

// Generate QR that encodes Japanese Unicode text
QrCode japaneseQr = QrWriter.Write("こんにちは世界");
// The library selects Kanji mode automatically
AnyBitmap qrImage = japaneseQr.Save();
qrImage.SaveAs("japanese-qr.png");
$vbLabelText   $csharpLabel

QR Code Output

QR Code Generator .NET Core: Read and Generate QR Codes with Just a Few Lines of Code: Image 6 - Output QR Code

Kanji encoding packs two bytes per module rather than eight bits, so a Japanese-language QR code at the same version stores significantly more characters than a UTF-8 byte-mode equivalent. For mixed content -- such as a URL followed by Japanese text -- IronQR segments the input and encodes each segment in the optimal mode. You do not need to specify segment boundaries or call encoding helpers manually; the encoding pipeline handles this for you.

This automatic selection also covers Extended Channel Interpretation (ECI) markers, which signal to scanners that non-standard character sets are in use. Applications targeting international markets can pass any Unicode string directly to QrWriter.Write() without separate configuration.

How Do You Use Payload Generators for Structured QR Data?

A QR code that encodes a plain URL works for simple link sharing, but many applications need to encode structured data -- WiFi credentials, contact cards in vCard format, or event data. Formatting these payloads manually is error-prone; a missing semicolon or incorrect field order will cause scanners to misinterpret the data.

IronQR provides payload helpers that build these structured strings correctly:

using IronQr;
using IronSoftware.Drawing;

// Generate QR code with URL payload
var urlQrCode = QrWriter.Write("https://ironsoftware.com/csharp/qr/");
// Save QR as PNG image file
AnyBitmap qrImage = urlQrCode.Save();
qrImage.SaveAs("url-qr-code.png");
Console.WriteLine("QR code generated successfully.");
using IronQr;
using IronSoftware.Drawing;

// Generate QR code with URL payload
var urlQrCode = QrWriter.Write("https://ironsoftware.com/csharp/qr/");
// Save QR as PNG image file
AnyBitmap qrImage = urlQrCode.Save();
qrImage.SaveAs("url-qr-code.png");
Console.WriteLine("QR code generated successfully.");
$vbLabelText   $csharpLabel

Created QR Code

QR Code Generator .NET Core: Read and Generate QR Codes with Just a Few Lines of Code: Image 7 - QR Code created from an URL

The QrWriter.Write() method accepts either a plain string or a structured payload object. For WiFi networks, the payload encodes the SSID, password, and security type in the format that Android and iOS scanners recognize. For contact information, the output follows the MeCard standard used by most mobile QR readers. The generate feature page documents all supported payload types and their required fields.

The library outputs images at configurable pixel dimensions. For production use, generating codes at a minimum of 200x200 pixels ensures reliable scanning from typical smartphone distances. Larger sizes benefit outdoor or printed applications where scanning distance exceeds one metre.

How Do You Customize QR Code Appearance?

IronQR gives you control over the visual appearance of generated codes without sacrificing scannability. You can change the foreground and background colors, apply custom branding, or embed a logo into the quiet zone at the centre.

using IronQr;
using IronSoftware.Drawing;

// Define custom colors for the QR code
var darkColor = Color.FromArgb(30, 30, 120);   // Deep navy foreground
var lightColor = Color.White;

var options = new QrOptions(QrErrorCorrectionLevel.High, maxVersion: 20)
{
    BackgroundColor = lightColor,
    Color = darkColor,
    // Embed a logo image into the QR center
    Logo = AnyBitmap.FromFile("logo.png")
};

QrCode styledQr = QrWriter.Write("https://ironsoftware.com/csharp/qr/", options);
AnyBitmap output = styledQr.Save();
output.SaveAs("branded-qr.png");
using IronQr;
using IronSoftware.Drawing;

// Define custom colors for the QR code
var darkColor = Color.FromArgb(30, 30, 120);   // Deep navy foreground
var lightColor = Color.White;

var options = new QrOptions(QrErrorCorrectionLevel.High, maxVersion: 20)
{
    BackgroundColor = lightColor,
    Color = darkColor,
    // Embed a logo image into the QR center
    Logo = AnyBitmap.FromFile("logo.png")
};

QrCode styledQr = QrWriter.Write("https://ironsoftware.com/csharp/qr/", options);
AnyBitmap output = styledQr.Save();
output.SaveAs("branded-qr.png");
$vbLabelText   $csharpLabel

Embedding a logo reduces the effective data area, so the library requires error correction level H when a logo is provided. The reserved quiet zone at the centre accounts for roughly 30% of the code surface, which is within the recovery capacity of the H level. The library enforces this constraint automatically -- if you set a lower error correction level alongside a logo, IronQR raises an exception with a descriptive message rather than producing a code that scans unreliably.

For ASP.NET Core applications, the ASP.NET Core QR code generator tutorial shows how to serve generated QR codes as image responses from a controller action. The output stream writes directly to the response without intermediate file I/O, which keeps latency low for high-traffic endpoints.

How Do You Read QR Codes in an ASP.NET Core Application?

Scanning QR codes server-side -- from uploaded images, document processing pipelines, or automated inspection systems -- is a common use case for the reading API. The ASP.NET QR code scanner guide covers the full controller and service setup, but the core reading pattern is the same as a console application:

using IronQr;
using IronSoftware.Drawing;
using Microsoft.AspNetCore.Mvc;

[ApiController]
[Route("api/qr")]
public class QrScanController : ControllerBase
{
    [HttpPost("scan")]
    public IActionResult Scan(IFormFile imageFile)
    {
        using var stream = imageFile.OpenReadStream();
        var bitmap = AnyBitmap.FromStream(stream);
        var imageInput = new QrImageInput(bitmap);
        var reader = new QrReader();
        var results = reader.Read(imageInput);

        var decoded = results.Select(r => new { r.Value, r.Url }).ToList();
        return Ok(decoded);
    }
}
using IronQr;
using IronSoftware.Drawing;
using Microsoft.AspNetCore.Mvc;

[ApiController]
[Route("api/qr")]
public class QrScanController : ControllerBase
{
    [HttpPost("scan")]
    public IActionResult Scan(IFormFile imageFile)
    {
        using var stream = imageFile.OpenReadStream();
        var bitmap = AnyBitmap.FromStream(stream);
        var imageInput = new QrImageInput(bitmap);
        var reader = new QrReader();
        var results = reader.Read(imageInput);

        var decoded = results.Select(r => new { r.Value, r.Url }).ToList();
        return Ok(decoded);
    }
}
$vbLabelText   $csharpLabel

The AnyBitmap.FromStream() method accepts any readable stream, so the same code path works for files uploaded through a form, images fetched from blob storage, or frames extracted from a video pipeline. The controller does not write any temporary files to disk, which matters for containerized deployments where the filesystem may be read-only.

For high-throughput scenarios, instantiate QrReader once per application lifetime as a singleton, since the ML model loading cost is paid on first construction. Subsequent Read() calls on the same instance are thread-safe and share the loaded model.

How Do You Generate QR Codes in a .NET MAUI Application?

The .NET MAUI QR code tutorial demonstrates full cross-platform generation on iOS, Android, macOS, and Windows. IronQR uses the SkiaSharp rendering backend when running on non-Windows platforms, giving consistent output across all MAUI targets.

using IronQr;
using IronSoftware.Drawing;

// Generate QR and convert to a byte array for display in MAUI
QrCode qr = QrWriter.Write("https://ironsoftware.com/csharp/qr/");
AnyBitmap bitmap = qr.Save();
byte[] imageBytes = bitmap.ExportBytes();

// Bind imageBytes to an <Image Source> in your MAUI page
using IronQr;
using IronSoftware.Drawing;

// Generate QR and convert to a byte array for display in MAUI
QrCode qr = QrWriter.Write("https://ironsoftware.com/csharp/qr/");
AnyBitmap bitmap = qr.Save();
byte[] imageBytes = bitmap.ExportBytes();

// Bind imageBytes to an <Image Source> in your MAUI page
$vbLabelText   $csharpLabel

On mobile targets, ExportBytes() returns a PNG byte array that you can feed directly into a StreamImageSource or write to an ImageButton. The MAUI scaffold requires no platform-specific code paths -- the same generation logic runs identically on all four MAUI targets.

For VB.NET projects the API surface is identical; only the syntax differs. The library ships a single NuGet package with no separate VB.NET assembly required.

What Are Your Next Steps?

IronQR covers the complete QR code lifecycle in .NET -- from basic generation and structured payload encoding to ML-powered reading of damaged or branded codes. The library handles Kanji encoding, error correction configuration, and cross-platform image output, leaving you to focus on the logic that is specific to your application.

To put what you have learned into practice:

Frequently Asked Questions

What .NET versions does IronQR support?

IronQR supports .NET Core 6, 7, 8, 9, and 10, as well as .NET Framework 4.6.2 and later. It also targets .NET Standard 2.0+, making it compatible with Xamarin, .NET MAUI, Blazor, and ASP.NET Core projects.

How do you read a QR code from an image file in C#?

Load the image using `AnyBitmap.FromFile()`, pass it to a `QrImageInput`, then call `QrReader.Read()`. The method returns an `IEnumerable` where each result contains the decoded value, URL, and corner coordinates.

What are the four QR code error correction levels?

The four levels are Low (L, ~7% recovery), Medium (M, ~15%), Quartile (Q, ~25%), and High (H, ~30%). Higher levels add redundancy modules, reducing net data capacity but improving scan reliability on damaged or partially obscured codes.

Can IronQR read QR codes that contain a logo or are partially damaged?

Yes. The ML-powered detection model in IronQR handles partially damaged codes, embedded logos, motion blur, and low-resolution inputs without requiring manual preprocessing.

How do you embed a logo into a QR code with IronQR?

Set the `Logo` property on a `QrOptions` object to an `AnyBitmap` of your logo image and set the error correction level to High. IronQR enforces this constraint automatically because a centred logo occupies roughly 30% of the code surface.

Does IronQR support Japanese and other Unicode characters?

Yes. Pass any Unicode string to `QrWriter.Write()` and the library automatically selects Kanji mode for Japanese characters or byte mode with ECI markers for other Unicode content.

How do you generate QR codes in an ASP.NET Core application?

Use `AnyBitmap.FromStream()` to read uploaded images and `QrWriter.Write()` to generate codes. Return the output as a `FileContentResult` with MIME type `image/png`. Instantiate `QrReader` as a singleton to amortise the ML model loading cost.

Is IronQR cross-platform?

Yes. IronQR uses a SkiaSharp rendering backend on non-Windows platforms, providing consistent QR generation and reading on macOS, Linux, iOS, and Android through .NET MAUI.

Jordi Bardia
Software Engineer
Jordi is most proficient in Python, C# and C++, when he isn’t leveraging his skills at Iron Software; he’s game programming. Sharing responsibilities for product testing, product development and research, Jordi adds immense value to continual product improvement. The varied experience keeps him challenged and engaged, and he ...
Read More

Iron Support Team

We're online 24 hours, 5 days a week.
Chat
Email
Call Me