- Usage Guide (English) — PNG, SVG, PDF, ASCII, Base64, Postscript, Artistic QR Codes
- Guia de Uso (Portugues) — PNG, SVG, PDF, ASCII, Base64, Postscript, QR Codes Artisticos
QRCoder.Core is a cross-platform .NET library for QR Code generation using SkiaSharp for image rendering. Compatible with Windows, Linux, macOS, and mobile (Xamarin / MAUI).
Based on QRCoder. Developed and maintained by AFONSOFT.
| Format | Class | Description |
|---|---|---|
| SKBitmap | QRCode |
SkiaSharp bitmap image (cross-platform) |
| PNG | PngByteQRCode |
PNG byte array (no System.Drawing needed) |
| SVG | SvgQRCode |
Scalable vector graphics string |
PdfByteQRCode |
PDF document as byte array | |
| ASCII | AsciiQRCode |
ASCII art for terminal output |
| Base64 | Base64QRCode |
Base64-encoded image string |
| Postscript | PostscriptQRCode |
Postscript/EPS format |
| Artistic | ArtQRCode |
Custom QR with rounded dots and backgrounds |
| BMP Bytes | BitmapByteQRCode |
Bitmap byte array |
The PayloadGenerator class provides formatted strings for common QR code use cases:
| Payload | Description |
|---|---|
Url |
Website URL |
WiFi |
Wi-Fi network credentials |
Mail |
Email with subject and body |
SMS |
SMS message |
PhoneNumber |
Phone number |
MMS |
Multimedia message |
Geolocation |
GPS coordinates |
CalendarEvent |
Calendar event (iCal/vEvent) |
ContactData |
vCard / MeCard contact |
BitcoinLikeCryptoCurrencyAddress |
Bitcoin/crypto payment |
Girocode |
European SEPA payment |
BezahlCode |
German payment standard |
SwissQrCode |
Swiss QR-bill payment |
OneTimePassword |
TOTP/HOTP for 2FA |
ShadowSocksConfig |
ShadowSocks proxy config |
Bookmark |
Browser bookmark |
SkypeCall |
Skype call link |
WhatsAppMessage |
WhatsApp message |
RussiaPaymentOrder |
Russian payment order |
SlovenianUpnQr |
Slovenian UPN QR payment |
| Metric | Coverage | Status |
|---|---|---|
| Line Coverage | 96.9% | Excellent |
| Branch Coverage | 92.6% | Excellent |
| Method Coverage | 96.0% | Excellent |
| Total Tests | 502 | All Passed |
Complete - Actively maintained with modern CI/CD pipelines.
QRCoder.Core provides a lightweight, cross-platform foundation for QR code generation that can be embedded in any .NET product — from mobile and web backends to desktop and CLI tooling. The goal is to remove platform-specific graphics dependencies while offering a predictable, extensible API for multiple output formats and industry-standard payloads.
The library is organized as a Clean Architecture pipeline:
- Generation:
QRCodeGeneratorbuilds an abstractQRCodeDatamatrix (models). - Payloads:
PayloadGeneratorformats standard data strings (Wi-Fi, vCard, SEPA, etc.) without coupling to rendering. - Rendering:
AbstractQRCodeimplementations produce output formats (PNG, SVG, PDF, ASCII, Base64, Postscript, Art, BMP) using SkiaSharp for cross-platform bitmap rendering. - Dependency rule:
AbstractionsandModelshave no external dependencies;RenderersandGeneratorsdepend only onModelsandAbstractions. - Quality gates: build with zero warnings, xUnit tests with ~97% line coverage, and static analysis via SonarCloud / Codecov / Snyk.
This library is compatible with multiple .NET versions:
- .NET Standard 2.1 — Maximum compatibility
- .NET 8.0 — LTS recommended
- .NET 10.0 — Latest version
- .NET Framework 4.8 — Legacy support
Technologies Used:
- C# — Primary programming language
- SkiaSharp — Cross-platform graphics library for rendering
- SkiaSharp.Views — SkiaSharp UI components
- System.Text.Encoding.CodePages — Additional code page support
- Microsoft.Extensions.ObjectPool — Reusable buffer pooling
- xUnit — Unit testing framework
- Shouldly — Assertion library
- coverlet — Cross-platform code coverage
- dotnet-reportgenerator-globaltool — Coverage report generation
- GitHub Actions — CI/CD automation
- SonarCloud — Static analysis and quality gates
- Codecov — Coverage reporting
- Snyk — Security vulnerability scanning
Install-Package QRCoder.Coredotnet add package QRCoder.Core<PackageReference Include="QRCoder.Core" Version="2.0.1" />Generate your first QR code with just a few lines of code:
using System;
using System.IO;
using QRCoder.Core.Generators;
using QRCoder.Core.Models;
using QRCoder.Core.Renderers;
using SkiaSharp;
// Create the QR Code generator
using var generator = new QRCodeGenerator();
using var data = generator.CreateQrCode("https://github.com/afonsoft/QRCoder.Core",
QRCodeGenerator.ECCLevel.M);
// Render as PNG bytes (cross-platform, no System.Drawing needed)
using var png = new PngByteQRCode(data);
byte[] pngBytes = png.GetGraphic(10);
File.WriteAllBytes("qrcode.png", pngBytes);
// Or render as SKBitmap
using var qrCode = new QRCode(data);
using var bitmap = qrCode.GetGraphic(10);using System;
using System.IO;
using QRCoder.Core.Generators;
using QRCoder.Core.Models;
using QRCoder.Core.Renderers;
using SkiaSharp;
// SVG output
using var svg = new SvgQRCode(data);
string svgString = svg.GetGraphic(10);
// ASCII output (great for terminal)
using var ascii = new AsciiQRCode(data);
Console.WriteLine(ascii.GetGraphic(1));
// PDF output
using var pdf = new PdfByteQRCode(data);
byte[] pdfBytes = pdf.GetGraphic(5);
// Base64 PNG (embed in HTML)
using var b64 = new Base64QRCode(data);
string base64Img = b64.GetGraphic(10);
// Use in HTML: <img src="data:image/png;base64,{base64Img}" />
// With custom colors
using var colorQr = new QRCode(data);
using var colorBmp = colorQr.GetGraphic(10, "#1a1a2e", "#e0e0e0");
// Postscript / EPS
using var ps = new PostscriptQRCode(data);
string psString = ps.GetGraphic(5);using System;
using System.IO;
using QRCoder.Core.Generators;
using QRCoder.Core.Models;
using QRCoder.Core.Renderers;
using SkiaSharp;
// Wi-Fi QR Code
var wifiPayload = new PayloadGenerator.WiFi("MyNetwork", "MyPassword",
PayloadGenerator.WiFi.Authentication.WPA);
using var gen = new QRCodeGenerator();
using var wifiData = gen.CreateQrCode(wifiPayload.ToString(), QRCodeGenerator.ECCLevel.M);
// URL QR Code
var urlPayload = new PayloadGenerator.Url("https://github.com/afonsoft/QRCoder.Core");
using var urlData = gen.CreateQrCode(urlPayload.ToString(), QRCodeGenerator.ECCLevel.M);
// Email QR Code
var mailPayload = new PayloadGenerator.Mail("[email protected]", "Subject", "Body text");
using var mailData = gen.CreateQrCode(mailPayload.ToString(), QRCodeGenerator.ECCLevel.M);
// Phone Number
var phonePayload = new PayloadGenerator.PhoneNumber("+5511999999999");
using var phoneData = gen.CreateQrCode(phonePayload.ToString(), QRCodeGenerator.ECCLevel.M);
// Contact Card (vCard)
var contactPayload = new PayloadGenerator.ContactData(
PayloadGenerator.ContactData.ContactOutputType.VCard3,
"Doe", "John",
phone: "+5511999999999",
email: "[email protected]");
using var contactData = gen.CreateQrCode(contactPayload.ToString(), QRCodeGenerator.ECCLevel.M);See the full Usage Guide for all output formats, payload types, advanced settings, and error correction levels.
| Level | Recovery | Use Case |
|---|---|---|
ECCLevel.L |
~7% | Maximum data capacity |
ECCLevel.M |
~15% | General purpose (recommended) |
ECCLevel.Q |
~25% | Higher reliability |
ECCLevel.H |
~30% | Maximum error recovery (logos, artistic QR) |
.
├── QRCoder.Core/ # Core library source code
│ ├── Abstractions/ # Abstract base class and contracts
│ │ └── AbstractQRCode.cs # Base class for all renderers
│ ├── Models/ # QR code data model and value objects
│ │ ├── QRCodeData.cs # QR code data structure
│ │ └── Size.cs # Rendering size value object
│ ├── Generators/ # QR code generation engine
│ │ ├── QRCodeGenerator.cs # Main QR code data generator
│ │ └── PayloadGenerator.cs# Payload formatters (WiFi, URL, etc.)
│ ├── Renderers/ # Output format renderers
│ │ ├── QRCode.cs # SKBitmap renderer
│ │ ├── PngByteQRCode.cs # PNG byte array renderer
│ │ ├── SvgQRCode.cs # SVG string renderer
│ │ ├── PdfByteQRCode.cs # PDF byte array renderer
│ │ ├── AsciiQRCode.cs # ASCII art renderer
│ │ ├── Base64QRCode.cs # Base64 image renderer
│ │ ├── PostscriptQRCode.cs# Postscript/EPS renderer
│ │ ├── ArtQRCode.cs # Artistic QR code renderer
│ │ └── BitmapByteQRCode.cs# BMP byte array renderer
│ ├── Extensions/ # SkiaSharp and helper extensions
│ ├── Exceptions/ # Custom exceptions
│ └── Assets/ # NuGet assets
├── QRCoder.Core.Tests/ # Unit tests (502 tests)
├── QRCoder.Core.Benchmarks/ # Performance benchmarks
├── docs/ # Usage guides
│ ├── en-US/usage-guide.md # English usage guide
│ └── pt-BR/guia-de-uso.md # Portuguese usage guide
├── .github/workflows/ # CI/CD pipelines
├── CHANGELOG.md # Version history
└── README.md / README.pt-br.md# English and Portuguese documentation
This project uses a complete CI/CD pipeline with GitHub Actions:
- Build & Pack — Main build with tests, coverage, and package creation
- Code Quality — Code analysis with Qodana and SonarCloud
- Security Scans — Security analysis with CodeQL, Snyk, and SonarCloud
- Publish NuGet — Automatic publishing to NuGet.org and GitHub Packages
- CI Build & Test — Continuous build and automated testing
# Build the project
dotnet build QRCoder.Core.sln --configuration Release
# Run all tests with coverage
dotnet test QRCoder.Core.Tests/QRCoder.Core.Tests.csproj \
--configuration Release \
--logger "trx;LogFileName=test-results.trx" \
--results-directory TestResults \
--collect:"XPlat Code Coverage"
# Generate HTML coverage report
dotnet tool install -g dotnet-reportgenerator-globaltool
reportgenerator \
-reports:"TestResults/**/coverage.cobertura.xml" \
-targetdir:"TestResults/CoverageReport" \
-reporttypes:"Html;XmlSummary;TextSummary"
# View report: open TestResults/CoverageReport/index.html-
Create a branch from
main:git checkout -b feature/your-feature
-
Make your changes following code conventions
-
Automated workflows will run:
- Build & Pack — Validates your code
- Code Quality — Analyzes quality
- Security Scan — Checks security
-
Pull Request: Create a PR to
main -
Review and Merge: After approval, your code will be merged
- Afonso Dutra Nogueira Filho (AFONSOFT) — Lead developer
This project is licensed under the MIT License. See the LICENSE.txt file for details.
See the full CHANGELOG.md for the complete version history.
- XML documentation for all public APIs (CS1591 removed from NoWarn).
- Repository structure, business vision, and technical vision sections in README.
BDDTests.cswith BDD-styleGiven/When/Thentests for QR code generation and rendering.
- Bumped package version to
2.0.1. - Updated CI, NuGet, SonarCloud, and Codecov badges in README files.
- Updated SonarCloud links to the correct project (
afonsoft_QRCoder.Core). - Consolidated CHANGELOG.md following Keep a Changelog and SemVer.
- Broken NuGet badge (now using shields.io).
- Broken CI build badge (now using
ci-build-test.yml). - SonarQube S2184 (integer division in
PdfByteQRCodemedia size). - SonarQube S4136 by grouping
GetGraphicoverloads inQRCodeandPdfByteQRCode.
- Reorganized codebase with SOLID and Clean Architecture folder structure.
- Multi-language documentation (en-US default + pt-BR).
- Updated target frameworks: .NET Standard 2.1, .NET 8.0, .NET 10.0, .NET Framework 4.8.
- SkiaSharp native library handling for Linux CI.
- Consolidated publish workflows.
- Migrated rendering to SkiaSharp.
- General project and documentation adjustments.
- Dependency updates.
- Action corrections.