Image Decoding
Use QrImageDecoder when only QR is expected, or MicroQrDecoder for direct Micro QR recognition. Use SymbolScanner for a unified result model across QR, Micro QR, linear barcodes, Data Matrix, PDF417, and Aztec. The capability matrix distinguishes pixel recognition from module-only decoding for every format.
QR-only decoding
using CodeGlyphX;
byte[] image = File.ReadAllBytes("qrcode.png");
var imageOptions = ImageDecodeOptions.Strict(
maxBytes: 8 * 1024 * 1024,
maxPixels: 8_000_000,
maxDimension: 1600);
var qrOptions = QrPixelDecodeOptions.Screen(
budgetMilliseconds: 500,
maxDimension: 1600);
if (QrImageDecoder.TryDecodeImage(image, imageOptions, qrOptions, out var decoded)) {
Console.WriteLine(decoded.Text);
}
Unified decoding
var options = new ScanOptions {
Formats = new[] { SymbolFormat.QrCode, SymbolFormat.MicroQrCode, SymbolFormat.DataMatrix, SymbolFormat.Code128 },
TimeoutMilliseconds = 750,
Qr = QrPixelDecodeOptions.Screen(budgetMilliseconds: 500, maxDimension: 1600),
Image = ImageDecodeOptions.Strict(
maxBytes: 8 * 1024 * 1024,
maxPixels: 8_000_000,
maxDimension: 1600)
};
var scan = SymbolScanner.Scan(image, options);
foreach (var symbol in scan.Symbols) {
Console.WriteLine($"{symbol.Format}: {symbol.Text}");
}
TimeoutMilliseconds covers compressed-image decoding, pixel conversion, and the complete recognition sequence. Cancellation and decoder budgets remain cooperative rather than hard real-time limits. Requested module-only formats are returned in ScanResult.UnsupportedFormats instead of being advertised as image-scannable.
Raw camera and interop buffers use the same scanner without a compressed-image codec:
var frame = new ImageFrame(pixels, width, height, stride, PixelFormat.Gray8);
var scan = SymbolScanner.Scan(frame, new ScanOptions {
Formats = new[] { SymbolFormat.QrCode, SymbolFormat.DataMatrix },
Region = new ImageRegion(0, 0, width, height)
});
Legacy facade and stream input
CodeGlyph remains available for compatibility and for stream-based input:
using var stream = File.OpenRead("barcode.png");
if (CodeGlyph.TryDecodeImage(stream, out var decoded)) {
Console.WriteLine(decoded.Text);
}
Multiple results
var scan = SymbolScanner.Scan(image, new ScanOptions {
Formats = new[] { SymbolFormat.QrCode },
MaxSymbols = 16,
Qr = QrPixelDecodeOptions.Robust().WithTileScan(enabled: true, tileGrid: 3)
});
foreach (var symbol in scan.Symbols) {
Console.WriteLine($"{symbol.Format}: {symbol.Text}");
}
Supported raster inputs
PNG, JPEG, WebP, BMP, GIF, TIFF, PPM/PGM/PBM/PAM, TGA, ICO/CUR, XBM, and XPM are handled by the managed image reader. PSD and PDF have narrower documented decode paths.
Resource-limit semantics
MaxBytesandMaxPixels:nullinherits the correspondingImageReaderglobal;0disables that per-call limit.MaxDimension: validates the original image first and then resizes the single-image RGBA output. Recognition uses only the resized pixels and does not retry at the original resolution. It does not reduce codec peak memory.RecognitionBudgetMilliseconds: cooperatively limits symbol recognition after raster decoding; it does not time the codec. Multi-formatCodeGlyphentry points apply it independently to each candidate decoder, so it is not a wall-clock limit for the complete candidate sequence.- Animation frame, duration, and per-frame pixel limits follow the same
null/0/positive inheritance model.
Known limits
- AVIF, HEIC, and JPEG 2000 are not supported.
ImageReader.DecodeRgba32returns the first GIF/WebP frame. Use the animation APIs for multiple frames.- Unsupported VP8 WebP animation interframes fail; CodeGlyphX does not substitute transparent or repeated pixels.
ImageReader.DecodeRgba32returns the first TIFF page. Use the TIFF page APIs for multi-page input.- PDF decode is limited to supported embedded JPEG/Flate image cases; PostScript requires external rasterization.
- The
netstandard2.0andnet472QR pixel fallback is intended for clean/generated images. Usenet8.0or newer for the full screenshot and stylized-code pipeline.
Optional external corpora
The repository keeps downloaded image and barcode corpora out of Git. Fetch them before the extended sample tests:
pwsh Build/Download-ImageSamples.ps1
pwsh Build/Download-ExternalSamples.ps1
Diagnostics
if (!CodeGlyph.TryDecodeImage(image, out var decoded, out var diagnostics, options: null)) {
Console.WriteLine(diagnostics.FailureReason);
Console.WriteLine(diagnostics.Failure);
}