Skip to content

1.1.0

Choose a tag to compare

@github-actions github-actions released this 18 Jul 09:04
· 62 commits to main since this release
Immutable release. Only release title and notes can be modified.

Overview

This release adds Micro QR (ISO/IEC 18004, M1–M4), generation, image rendering, and decoding, alongside the existing Standard QR support. The decoder pipeline also gets SIMD/NEON optimizations on AArch64, and Standard QR masking is faster with AVX2.

QRCodeImageBuilder and the new MicroQRCodeImageBuilder now share a common base class (QRCodeImageBuilderBase<TSelf>). Fluent call chains are source-compatible; recompile if you reference the library as a binary dependency.


Key change: Micro QR support

Micro QR is a compact symbology for small payloads (11×11 to 17×17 modules). This release provides:

API Purpose
MicroQRCodeGenerator Encode text to MicroQRCodeData
MicroQRCodeImageBuilder Render PNG / JPEG / WebP / SVG
MicroQRCodeDecoder Decode from matrix or image

QRCodeDecoder remains Standard QR only. Use MicroQRCodeDecoder for Micro QR images.

image

Generate (one-liner)

using SkiaSharp.QrCode;
using SkiaSharp.QrCode.Image;

// M2-L numeric example; auto-selects the smallest version that fits
var pngBytes = MicroQRCodeImageBuilder.GetPngBytes("01234567", MicroQREccLevel.L, size: 256);
File.WriteAllBytes("microqr.png", pngBytes);

Generate (builder — colors, shapes, gradient)

using SkiaSharp;
using SkiaSharp.QrCode;
using SkiaSharp.QrCode.Image;

var gradient = new GradientOptions(
    [SKColor.Parse("00B894"), SKColor.Parse("0984E3")],
    GradientDirection.TopLeftToBottomRight);

var pngBytes = new MicroQRCodeImageBuilder("SKU-42")
    .WithModulePixelSize(14)
    .WithErrorCorrection(MicroQREccLevel.M)
    .WithColors(codeColor: SKColor.Parse("2D3436"), backgroundColor: SKColors.White)
    .WithModuleShape(RoundedRectangleModuleShape.Default, sizePercent: 0.92f)
    .WithGradient(gradient)
    .ToByteArray();

Decode (matrix and image)

using SkiaSharp;
using SkiaSharp.QrCode;

// From matrix
var micro = MicroQRCodeGenerator.CreateMicroQRCode("01234567", MicroQREccLevel.L);
if (MicroQRCodeDecoder.TryDecode(micro, out var text, out var info))
{
    Console.WriteLine($"{text} ({info.Version}, ECC {info.EccLevel})");
}

// From image — use MicroQRCodeDecoder, not QRCodeDecoder
using var bitmap = SKBitmap.Decode("microqr.png");
if (MicroQRCodeDecoder.TryDecode(bitmap, out var scanned, out _))
{
    Console.WriteLine(scanned);
}

Micro QR constraints: M1 = numeric + error detection only; M2–M4 support numeric/alphanumeric/byte modes with version-specific ECC limits. No ECI mode; no icon overlay or custom finder styling (single finder pattern, limited ECC headroom).


Breaking changes

Binary: QRCodeImageBuilderBase<TSelf>

QRCodeImageBuilder and MicroQRCodeImageBuilder now derive from QRCodeImageBuilderBase<TSelf>. Shared methods (WithSize, WithModulePixelSize, WithFormat, WithQuietZone, WithColors, WithModuleShape, WithGradient, SaveTo, ToByteArray, etc.) moved to the base class.

  • Source compatible — no code changes needed.
  • Binary breaking — recompile assemblies compiled against 1.0.x.

WithQuietZone() default parameter removed

WithQuietZone(int size = 4) is now WithQuietZone(int size) with no default. Calling WithQuietZone() with no argument no longer compiles. Remove the call to use the builder default (4 modules for Standard QR, 2 for Micro QR).

// Before (1.0.x) — no longer compiles
new QRCodeImageBuilder("content").WithQuietZone().ToByteArray();

// After (1.1.0) — omit the call, or pass an explicit value
new QRCodeImageBuilder("content").ToByteArray();
new QRCodeImageBuilder("content").WithQuietZone(4).ToByteArray();

Other improvements

  • Performance: AVX2 masking for Standard QR; NEON optimizations for decoder stages (finder pattern, alignment, sampling, text analysis) on ARM64.
  • Bug fix: FinderPatternShape background color no longer renders as black on GPU surfaces (#338).

Migration

See docs/migration.md for details.

What's Changed

Full Changelog: 1.0.1...1.1.0