- 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<PackageReferenceInclude="QRCoder.Core"Version="2.0.1" />Generate your first QR code with just a few lines of code:
usingSystem;usingSystem.IO;usingQRCoder.Core.Generators;usingQRCoder.Core.Models;usingQRCoder.Core.Renderers;usingSkiaSharp;// Create the QR Code generatorusingvargenerator=newQRCodeGenerator();usingvardata=generator.CreateQrCode("https://github.com/afonsoft/QRCoder.Core",QRCodeGenerator.ECCLevel.M);// Render as PNG bytes (cross-platform, no System.Drawing needed)usingvarpng=newPngByteQRCode(data);byte[]pngBytes=png.GetGraphic(10);File.WriteAllBytes("qrcode.png",pngBytes);// Or render as SKBitmapusingvarqrCode=newQRCode(data);usingvarbitmap=qrCode.GetGraphic(10);usingSystem;usingSystem.IO;usingQRCoder.Core.Generators;usingQRCoder.Core.Models;usingQRCoder.Core.Renderers;usingSkiaSharp;// SVG outputusingvarsvg=newSvgQRCode(data);stringsvgString=svg.GetGraphic(10);// ASCII output (great for terminal)usingvarascii=newAsciiQRCode(data);Console.WriteLine(ascii.GetGraphic(1));// PDF outputusingvarpdf=newPdfByteQRCode(data);byte[]pdfBytes=pdf.GetGraphic(5);// Base64 PNG (embed in HTML)usingvarb64=newBase64QRCode(data);stringbase64Img=b64.GetGraphic(10);// Use in HTML: <img src="data:image/png;base64,{base64Img}" />// With custom colorsusingvarcolorQr=newQRCode(data);usingvarcolorBmp=colorQr.GetGraphic(10,"#1a1a2e","#e0e0e0");// Postscript / EPSusingvarps=newPostscriptQRCode(data);stringpsString=ps.GetGraphic(5);usingSystem;usingSystem.IO;usingQRCoder.Core.Generators;usingQRCoder.Core.Models;usingQRCoder.Core.Renderers;usingSkiaSharp;// Wi-Fi QR CodevarwifiPayload=newPayloadGenerator.WiFi("MyNetwork","MyPassword",PayloadGenerator.WiFi.Authentication.WPA);usingvargen=newQRCodeGenerator();usingvarwifiData=gen.CreateQrCode(wifiPayload.ToString(),QRCodeGenerator.ECCLevel.M);// URL QR CodevarurlPayload=newPayloadGenerator.Url("https://github.com/afonsoft/QRCoder.Core");usingvarurlData=gen.CreateQrCode(urlPayload.ToString(),QRCodeGenerator.ECCLevel.M);// Email QR CodevarmailPayload=newPayloadGenerator.Mail("test@example.com","Subject","Body text");usingvarmailData=gen.CreateQrCode(mailPayload.ToString(),QRCodeGenerator.ECCLevel.M);// Phone NumbervarphonePayload=newPayloadGenerator.PhoneNumber("+5511999999999");usingvarphoneData=gen.CreateQrCode(phonePayload.ToString(),QRCodeGenerator.ECCLevel.M);// Contact Card (vCard)varcontactPayload=newPayloadGenerator.ContactData(PayloadGenerator.ContactData.ContactOutputType.VCard3,"Doe","John",phone:"+5511999999999",email:"john.doe@example.com");usingvarcontactData=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.htmlCreate 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
mainReview 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.