SkiaSharp.QrCode
High-performance QR code generation with SkiaSharp integration.
Install / Use
/learn @guitarrapc/SkiaSharp.QrCodeREADME
SkiaSharp.QrCode
SkiaSharp.QrCode provides high-performance QR code generation with SkiaSharp integration.

Benchmark results comparing SkiaSharp.QrCode with other libraries. See samples/Benchmark for details.
Many existing QR code libraries rely on System.Drawing, which has well-known GDI+ limitations and cross-platform issues. SkiaSharp.QrCode was created to provide high performance, minimum memory allocation, a simpler and more intuitive API while leveraging SkiaSharp's cross-platform capabilities. Generate a QR code in a single line, or customize every detail - the choice is yours.
You can create professional-looking QR codes like this with just a few lines of code:
<p float="left"> <img src="samples/ConsoleApp/samples/pattern15_instagram_frame.png" width="250" alt="Instagram-style"/> <img src="samples/ConsoleApp/samples/pattern6_builder_gradient.png" width="250" alt="Gradient QR"/> <img src="samples/ConsoleApp/samples/pattern7_builder_icon.png" width="250" alt="Icon QR"/> </p>See samples/ConsoleApp for code examples generating these styles.
Overview
SkiaSharp.QrCode is a modern, high-performance QR code generation library built on SkiaSharp. SkiaSharp.QrCode allocates memory only for the actual QR code data, with zero additional allocations during processing.
- Simple API: One-liner QR code generation with sensible defaults
- High Performance: Optimal speed and minimum memory allocation
- Highly Customizable: Gradients, icons, custom shapes, colors, and more
- Cross-Platform: Windows, Linux, macOS, iOS, Android, WebAssembly
- Zero Dependencies: QR generation without external libraries (SkiaSharp for rendering only)
- No System.Drawing: Avoids GDI+ issues and Windows dependencies
- NativeAOT Ready: Full support for .NET Native AOT compilation
- Modern .NET: .NET Standard 2.0, 2.1, .NET 8+
Installation
Visit SkiaSharp.QrCode on NuGet.org
dotnet add package SkiaSharp.QrCode
Quick Start
Simplest Example
Single line QR code generation:
using SkiaSharp.QrCode.Image;
// one-liner save to file
QRCodeImageBuilder.SavePng("Hello", "qrcode.png");
// Or get bytes
var pngBytes = QRCodeImageBuilder.GetPngBytes("https://example.com");
Common Use Cases
Generate QR Code for URL.
var pngBytes = QRCodeImageBuilder.GetPngBytes("https://example.com");
File.WriteAllBytes("qrcode.png", pngBytes);
WiFi QR Code.
var wifiString = "WIFI:T:WPA;S:MyNetwork;P:MyPassword;;";
QRCodeImageBuilder.SavePng(wifiString, "wifi-qr.png");
Generate with Custom Settings.
var qrCode = new QRCodeImageBuilder("https://example.com")
.WithSize(512, 512)
.WithErrorCorrection(ECCLevel.H)
.ToByteArray();
Save Directly to Stream
using SkiaSharp.QrCode.Image;
using var stream = File.OpenWrite("qrcode.png");
QRCodeImageBuilder.SavePng("Your content here", stream, ECCLevel.M, size: 512);
Migration
- v0.11.0 introduces further improvements to Icon handling. See the IconData section below.
- v0.9.0 introduces significant performance improvements and API changes. Here's what you need to know to upgrade:
from 0.10.0 to 0.11.0 and higher
Take advantage of new capabilities:
- Logo customization - Now you can customize center placed logos. Library offers icons with both images and text.
For complete migration details and examples, see Release 0.11.0.
⚠️ IconData.Data changed Icon from SKBitmap to IconShape
Before (0.10.0):
using var bitmap = SKBitmap.Decode(File.ReadAllBytes(iconPath));
// Old code
var icon = new IconData
{
Icon = bitmap;
IconSizePercent = 15,
IconBorderWidth = 10
};
After (0.11.0):
using var bitmap = SKBitmap.Decode(File.ReadAllBytes(iconPath));
// New code Image only (Short hand)
var icon = IconData.FromImage(bitmap, iconSizePercent: 15, iconBorderWidth: 10);
// New code Image only
var icon = new IconData
{
Icon = new ImageIconShape(bitmap),
IconSizePercent = 15,
IconBorderWidth = 10
};
// New approach with text
var icon = new IconData
{
Icon = new ImageTextIconShape(bitmap, "Text", SKColors.Black, font),
IconSizePercent = 15,
IconBorderWidth = 10
};
from 0.8.0 to 0.9.0 and higher
Take advantage of new capabilities:
- Gradient colors - Create eye-catching QR codes with color gradients
- Enhanced customization - More control over module shapes and colors
- Better performance - Dramatically faster generation with lower memory usage
For complete migration details and examples, see Release 0.9.0.
🔄 Primary API Change: QrCode → QRCodeImageBuilder
The QrCode class is now obsolete. Replace it with QRCodeImageBuilder:
Before (0.8.0):
var qrCode = new QrCode(content, new Vector2Slim(512, 512), SKEncodedImageFormat.Png);
using (var output = new FileStream(path, FileMode.OpenOrCreate))
{
qrCode.GenerateImage(output);
}
After (0.9.0) - Simple approach:
var pngBytes = QRCodeImageBuilder.GetPngBytes(content);
File.WriteAllBytes(path, pngBytes);
After (0.9.0) - Builder pattern:
using var stream = File.OpenWrite(path);
new QRCodeImageBuilder(content)
.WithSize(512, 512)
.WithErrorCorrection(ECCLevel.H)
.SaveTo(stream);
🗑️ Remove using Statements
QRCodeData and QRCodeRenderer are no longer IDisposable:
Before (0.8.0):
using var qrCodeData = QRCodeGenerator.CreateQrCode("Hello", ECCLevel.L);
using var renderer = new QRCodeRenderer();
renderer.Render(...);
After (0.9.0):
var qrCodeData = QRCodeGenerator.CreateQrCode("Hello", ECCLevel.L);
QRCodeRenderer.Render(...); // Now a static method
📦 Update Namespace for IconData
If using icons in QR codes:
// Add this namespace
using SkiaSharp.QrCode.Image;
🚫 Removed Features
The following features have been removed:
forceUtf8parameter- ISO-8859-2 encoding support
- Compression feature
- Kanji encoding mode
If you were using these features, you'll need to adjust your code accordingly.
forceUtf8: SkiaSharp.QrCode now automatically selects UTF-8 when needed.- ISO-8859-2 and Kanji: Currently not supported; UTF-8 is recommended for most use cases.
- Compression: Removed to simplify the API and improve performance. Please handle compression externally if needed.
Here's an example of how to handle compression externally using NativeCompressions:
// compression to zstandard ...
var qrCodeData = QRCodeGenerator.CreateQrCode("Hello", ECCLevel.L);
var src = qrCodeData.GetRawData();
var size = qrCodeData.GetRawDataSize();
var maxSize = NativeCompressions.Zstandard.GetMaxCompressedLength(size);
var compressed = new byte[maxSize];
NativeCompressions.Zstandard.Compress(src, compressed, NativeCompressions.ZstandardCompressionOptions.Default);
// decompression from zstandard ...
var decompressed = NativeCompressions.Zstandard.Decompress(compressed);
// render QR code
var qr = new QRCodeData(decompressed, 4);
var pngBytes = QRCodeImageBuilder.GetPngBytes(qr, 512);
File.WriteAllBytes(path, pngBytes);
API Overview
SkiaSharp.QrCode provides three main APIs for different use cases.
Recommendation: Start with QRCodeImageBuilder for most scenarios. Use QRCodeRenderer when you need canvas control. Use QRCodeGenerator only for custom rendering implementations.
| Feature | QRCodeImageBuilder | QRCodeRenderer | QRCodeGenerator | | --- | --- | --- | --- | | Ease of use | High | Medium | Low | | Flexibility | Medium | High | Highest | | Built-in rendering | Yes | Yes | No | | Custom canvas control | No | Yes | N/A | | Recommended for beginners | Yes | No | No |
QRCodeImageBuilder (Recommended)
Best for Most use cases - simple to advanced QR code generation. The high-level, fluent API for generating QR codes with minimal code. Provides a builder pattern with sensible defaults and extensive customization options.
Key Features:
- One-liner generation with
GetPngBytes(),SavePng() - Fluent API with
WithXxx()methods - Built-in support for colors, gradients, icons, shapes
- Multiple output formats (PNG, JPEG, WebP)
- Stream and byte array output
When to use:
- Quick QR code generation
- Standard customization needs
- File or stream output
Example:
var pngBytes = QRCodeImageBuilder.GetPngBytes("content");
QRCodeRenderer (Advanced)
Best for Custom rendering with full control over the canvas. The mid-level API that renders QR data onto an existing SkiaSharp canvas. Useful when you need to integrate QR codes into existing graphics or add custom post-processing.
Key Features:
- Render to existing
SKCanvas - Full control over rendering area (
SKRect) - Combine with other SkiaSharp drawing operations
- Custom effects and post-processing
When to use:
- Integrating QR codes into existing graphics
- Adding custom decorations or effects
- Mult
