Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions QRCoder.Core/Abstractions/AbstractQRCode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,18 @@ namespace QRCoder.Core.Abstractions
using QRCoder.Core.Models;

/// <summary>
/// AbstractQRCode
/// Abstract base class for all QR code renderers. Provides shared lifecycle management
/// and access to the underlying <see cref="QRCodeData"/> used for rendering.
/// </summary>
public abstract class AbstractQRCode : IDisposable
{
/// <summary>
/// QRCodeData
/// The QR code data used for rendering. Contains the module matrix that defines the QR code pattern.
/// </summary>
protected QRCodeData QrCodeData { get; set; }

/// <summary>
/// AbstractQRCode
/// Initializes a new instance of the renderer and sets a process-wide regex timeout of 500ms.
/// </summary>
protected AbstractQRCode()
{
Expand All @@ -27,9 +28,9 @@ protected AbstractQRCode()
}

/// <summary>
/// AbstractQRCode
/// Initializes a new instance of the renderer with the specified QR code data.
/// </summary>
/// <param name="data"></param>
/// <param name="data">The <see cref="QRCodeData"/> generated by <see cref="QRCoder.Core.Generators.QRCodeGenerator"/>.</param>
protected AbstractQRCode(QRCodeData data) : this()
{
this.QrCodeData = data;
Expand Down
119 changes: 95 additions & 24 deletions QRCoder.Core/Assets/nuget-readme.md
Original file line number Diff line number Diff line change
@@ -1,42 +1,113 @@
## About
# QRCoder.Core

QRCoder.Core is a simple library, written in C#.NET, based on [QrCode](https://github.com/codebude/QRCoder) which enables you to create QR codes. It is available as a .NET Core version on NuGet. It uses SkiaSharp for cross-platform compatibility.
A cross-platform .NET library for QR Code generation using **SkiaSharp**. Compatible with **Windows**, **Linux**, **macOS**, and **mobile** (Xamarin / MAUI).

Based on [QRCoder](https://github.com/codebude/QRCoder). Supports **.NET Standard 2.1**, **.NET 8.0**, **.NET 10.0**, and **.NET Framework 4.8**.

***
---

## Documentation
## Quick Start

👉 *Your first place to go should be our wiki. Here you can find a detailed documentation of the QRCoder and its functions.*
* [**QRCode Wiki**](https://github.com/codebude/QRCoder/wiki) or [**QRCode.Core Wiki**](https://github.com/afonsoft/QRCoder.Core/wiki)
```csharp
using QRCoder.Core;

// Generate QR code data
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);
```

## Output Formats

## Usage / Quick start
| Format | Class | Example |
|--------|-------|---------|
| **PNG** | `PngByteQRCode` | `new PngByteQRCode(data).GetGraphic(10)` → `byte[]` |
| **SVG** | `SvgQRCode` | `new SvgQRCode(data).GetGraphic(10)` → `string` |
| **PDF** | `PdfByteQRCode` | `new PdfByteQRCode(data).GetGraphic(5)` → `byte[]` |
| **ASCII** | `ASCIIQRCode` | `new ASCIIQRCode(data).GetGraphic(1)` → `string` |
| **Base64** | `Base64QRCode` | `new Base64QRCode(data).GetGraphic(10)` → `string` |
| **SKBitmap** | `QRCode` | `new QRCode(data).GetGraphic(10)` → `SKBitmap` |
| **Postscript** | `PostscriptQRCode` | `new PostscriptQRCode(data).GetGraphic(5)` → `string` |
| **Artistic** | `ArtQRCode` | `new ArtQRCode(data).GetGraphic(10)` → `SKBitmap` |
| **BMP** | `BitmapByteQRCode` | `new BitmapByteQRCode(data).GetGraphic(10)` → `byte[]` |

You only need four lines of code, to generate and view your first QR code.
## Multiple Formats Example

```csharp
using (QRCodeGenerator qrGenerator = new QRCodeGenerator())
using (QRCodeData qrCodeData = qrGenerator.CreateQrCode("The text which should be encoded.", QRCodeGenerator.ECCLevel.Q))
using (QRCode qrCode = new QRCode(qrCodeData))
{
Bitmap qrCodeImage = qrCode.GetGraphic(20);
}
using QRCoder.Core;

using var gen = new QRCodeGenerator();
using var data = gen.CreateQrCode("Hello World", QRCodeGenerator.ECCLevel.M);

// SVG
using var svg = new SvgQRCode(data);
string svgString = svg.GetGraphic(10);

// ASCII (terminal)
using var ascii = new ASCIIQRCode(data);
Console.WriteLine(ascii.GetGraphic(1));

// PDF
using var pdf = new PdfByteQRCode(data);
byte[] pdfBytes = pdf.GetGraphic(5);

// With custom colors
using var qr = new QRCode(data);
using var bitmap = qr.GetGraphic(10, "#1a1a2e", "#e0e0e0");
```

### Optional parameters and overloads
## Payload Types

The GetGraphics-method has some more overloads. The first two enable you to set the color of the QR code graphic. One uses Color-class-types, the other HTML hex color notation.
Generate formatted QR code content for common use cases:

```csharp
//Set color by using Color-class types
Bitmap qrCodeImage = qrCode.GetGraphic(20, Color.DarkRed, Color.PaleGreen, true);
using QRCoder.Core;

//Set color by using HTML hex color notation
Bitmap qrCodeImage = qrCode.GetGraphic(20, "#000ff0", "#0ff000");
using var gen = new QRCodeGenerator();

// Wi-Fi
var wifi = new PayloadGenerator.WiFi("MyNetwork", "MyPassword",
PayloadGenerator.WiFi.Authentication.WPA);
using var wifiData = gen.CreateQrCode(wifi.ToString(), QRCodeGenerator.ECCLevel.M);

// URL
var url = new PayloadGenerator.Url("https://github.com/afonsoft/QRCoder.Core");
using var urlData = gen.CreateQrCode(url.ToString(), QRCodeGenerator.ECCLevel.M);

// Email
var mail = new PayloadGenerator.Mail("test@example.com", "Subject", "Body");
using var mailData = gen.CreateQrCode(mail.ToString(), QRCodeGenerator.ECCLevel.M);

// Phone Number
var phone = new PayloadGenerator.PhoneNumber("+1234567890");
using var phoneData = gen.CreateQrCode(phone.ToString(), QRCodeGenerator.ECCLevel.M);

// Contact Card (vCard)
var contact = new PayloadGenerator.ContactData(
PayloadGenerator.ContactData.ContactOutputType.VCard3,
"Doe", "John", phone: "+1234567890", email: "john@example.com");
using var contactData = gen.CreateQrCode(contact.ToString(), QRCodeGenerator.ECCLevel.M);
```

The other overload enables you to render a logo/image in the center of the QR code.
Supported payloads: URL, WiFi, Mail, SMS, PhoneNumber, MMS, Geolocation, CalendarEvent, ContactData, Bitcoin, Girocode, BezahlCode, SwissQrCode, OneTimePassword, ShadowSocksConfig, Bookmark, SkypeCall, WhatsAppMessage, and more.

```csharp
Bitmap qrCodeImage = qrCode.GetGraphic(20, Color.Black, Color.White, (Bitmap)Bitmap.FromFile("C:\\myimage.png"));
```
## 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 recovery (logos, artistic QR) |

## Documentation & Source

- **Repository**: [https://github.com/afonsoft/QRCoder.Core](https://github.com/afonsoft/QRCoder.Core)
- **Usage Guide**: [https://github.com/afonsoft/QRCoder.Core/blob/main/docs/en-US/usage-guide.md](https://github.com/afonsoft/QRCoder.Core/blob/main/docs/en-US/usage-guide.md)
- **Issues**: [https://github.com/afonsoft/QRCoder.Core/issues](https://github.com/afonsoft/QRCoder.Core/issues)
- **License**: MIT
3 changes: 2 additions & 1 deletion QRCoder.Core/Exceptions/DataTooLongException.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
namespace QRCoder.Core.Exceptions
{
/// <summary>
/// DataTooLongException
/// Thrown when the input data exceeds the maximum capacity allowed by the QR code standard
/// for the specified error correction level, encoding mode, and optional fixed version.
/// </summary>
public class DataTooLongException : Exception
{
Expand Down
10 changes: 10 additions & 0 deletions QRCoder.Core/Extensions/SKColorExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,23 @@

namespace QRCoder.Core.Extensions
{
/// <summary>
/// Extension methods for converting <see cref="SKColor"/> values to and from hexadecimal string notation.
/// </summary>
public static class SKColorExtensions
{
/// <summary>
/// Converts this color to an ARGB hexadecimal string (e.g., "#FF000000" for opaque black).
/// </summary>
public static string ToHex(this SKColor color)
{
return string.Format(CultureInfo.InvariantCulture, "#{0:X2}{1:X2}{2:X2}{3:X2}", color.Alpha, color.Red, color.Green, color.Blue);
}

/// <summary>
/// Parses a hexadecimal color string (#RRGGBB or #AARRGGBB) into an <see cref="SKColor"/>.
/// Returns <see cref="SKColors.Transparent"/> for null, empty, or invalid input.
/// </summary>
public static SKColor FromHex(string hex)
{
if (string.IsNullOrEmpty(hex))
Expand Down
4 changes: 2 additions & 2 deletions QRCoder.Core/Extensions/StringValueAttribute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public class StringValueAttribute : Attribute
#region Properties

/// <summary>
/// Holds the alue in an enum
/// Holds the string value associated with the enum member.
/// </summary>
public string StringValue { get; protected set; }

Expand All @@ -27,7 +27,7 @@ public StringValueAttribute(string value)
}

/// <summary>
/// CustomExtensions
/// Extension methods for retrieving <see cref="StringValueAttribute"/> values from enum members.
/// </summary>
public static class CustomExtensions
{
Expand Down
36 changes: 20 additions & 16 deletions QRCoder.Core/Models/QRCodeData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,15 @@
namespace QRCoder.Core.Models
{
/// <summary>
/// QRCodeData
/// Stores the encoded QR code data as a module matrix. Each element in the matrix represents
/// a row of modules (black/white squares). Generated by <see cref="QRCoder.Core.Generators.QRCodeGenerator"/>
/// and consumed by renderer classes to produce visual output.
/// </summary>
public class QRCodeData : IDisposable
{
/// <summary>
/// Module Matrix
/// The module matrix representing the QR code. Each <see cref="BitArray"/> is a row,
/// where true = dark module and false = light module.
/// </summary>
public List<BitArray> ModuleMatrix { get; set; }

Expand All @@ -25,20 +28,20 @@ public QRCodeData(int version)
}

/// <summary>
/// QRCodeData
/// Loads QR code data from a file in the proprietary QRR format.
/// </summary>
/// <param name="pathToRawData">pathToRawData</param>
/// <param name="compressMode">compressMode</param>
/// <param name="pathToRawData">Path to the QRR file containing saved QR code data.</param>
/// <param name="compressMode">Compression mode used when the file was saved.</param>
public QRCodeData(string pathToRawData, Compression compressMode) : this(File.ReadAllBytes(pathToRawData), compressMode)
{
}

/// <summary>
/// QRCodeData
/// Loads QR code data from a byte array in the proprietary QRR format.
/// </summary>
/// <param name="rawData">rawData</param>
/// <param name="compressMode">compressMode</param>
/// <exception cref="Exception">Exception</exception>
/// <param name="rawData">Byte array containing saved QR code data in QRR format.</param>
/// <param name="compressMode">Compression mode used when the data was saved.</param>
/// <exception cref="InvalidOperationException">Thrown when the raw data does not match the QRR file format.</exception>
public QRCodeData(byte[] rawData, Compression compressMode)
{
var bytes = new List<byte>(rawData);
Expand Down Expand Up @@ -105,10 +108,11 @@ public QRCodeData(byte[] rawData, Compression compressMode)
}

/// <summary>
/// GetRawData
/// Serializes the QR code data into a byte array in the proprietary QRR format,
/// with optional Deflate or GZip compression.
/// </summary>
/// <param name="compressMode">compressMode</param>
/// <returns></returns>
/// <param name="compressMode">The compression algorithm to apply to the output.</param>
/// <returns>A byte array containing the QR code data in QRR format.</returns>
public byte[] GetRawData(Compression compressMode)
{
var bytes = new List<byte>();
Expand Down Expand Up @@ -172,10 +176,10 @@ public byte[] GetRawData(Compression compressMode)
}

/// <summary>
/// SaveRawData
/// Saves the QR code data to a file in the proprietary QRR format.
/// </summary>
/// <param name="filePath">filePath</param>
/// <param name="compressMode">compressMode</param>
/// <param name="filePath">The path where the QRR file will be written.</param>
/// <param name="compressMode">The compression algorithm to apply.</param>
public void SaveRawData(string filePath, Compression compressMode)
{
File.WriteAllBytes(filePath, GetRawData(compressMode));
Expand Down Expand Up @@ -216,7 +220,7 @@ protected virtual void Dispose(bool disposing)
}

/// <summary>
/// Compression
/// Specifies the compression algorithm used when saving or loading QR code data.
/// </summary>
public enum Compression
{
Expand Down
10 changes: 10 additions & 0 deletions QRCoder.Core/Models/Size.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,18 @@
namespace QRCoder.Core.Models
{
/// <summary>
/// Represents the dimensions (width and height) of a QR code rendering area.
/// </summary>
public struct Size
{
/// <summary>
/// The width of the rendering area in the target unit (pixels, points, etc.).
/// </summary>
public double Width { get; set; }

/// <summary>
/// The height of the rendering area in the target unit (pixels, points, etc.).
/// </summary>
public double Height { get; set; }

public Size(double width, double height)
Expand Down
3 changes: 2 additions & 1 deletion QRCoder.Core/Renderers/ArtQRCode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
namespace QRCoder.Core.Renderers
{
/// <summary>
/// ArtQRCode
/// Renders a QR code with artistic styling using rounded dots instead of square modules.
/// Supports custom dot colors, background images, and quiet zone control.
/// </summary>
public class ArtQRCode : AbstractQRCode
{
Expand Down
3 changes: 2 additions & 1 deletion QRCoder.Core/Renderers/AsciiQRCode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
namespace QRCoder.Core.Renderers
{
/// <summary>
/// AsciiQRCode
/// Renders a QR code as ASCII art text, suitable for terminal/console output.
/// Each module is represented by configurable dark and light character strings.
/// </summary>
public class AsciiQRCode : AbstractQRCode
{
Expand Down
3 changes: 2 additions & 1 deletion QRCoder.Core/Renderers/Base64QRCode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
namespace QRCoder.Core.Renderers
{
/// <summary>
/// Base64QRCode
/// Renders a QR code as a Base64-encoded image string. Useful for embedding QR codes
/// directly in HTML img tags or CSS without requiring a separate file.
/// </summary>
public class Base64QRCode : AbstractQRCode
{
Expand Down
3 changes: 2 additions & 1 deletion QRCoder.Core/Renderers/BitmapByteQRCode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
namespace QRCoder.Core.Renderers
{
/// <summary>
/// SKBitmapByteQRCode
/// Renders a QR code as a raw BMP (bitmap) byte array. Produces an uncompressed
/// 24-bit color bitmap image suitable for further processing or display.
/// </summary>
// ReSharper disable once InconsistentNaming
public class SKBitmapByteQRCode : AbstractQRCode
Expand Down
3 changes: 2 additions & 1 deletion QRCoder.Core/Renderers/PdfByteQRCode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
namespace QRCoder.Core.Renderers
{
/// <summary>
/// PdfByteQRCode
/// Renders a QR code as a PDF document byte array. Generates a minimal valid PDF
/// containing the QR code image with configurable colors and quiet zone.
/// </summary>
// ReSharper disable once InconsistentNaming
public class PdfByteQRCode : AbstractQRCode
Expand Down
3 changes: 2 additions & 1 deletion QRCoder.Core/Renderers/PngByteQRCode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
namespace QRCoder.Core.Renderers
{
/// <summary>
/// PngByteQRCode
/// Renders a QR code as a PNG image byte array. This renderer does not require System.Drawing
/// and works cross-platform on Windows, Linux, macOS, and mobile.
/// </summary>
public sealed class PngByteQRCode : AbstractQRCode
{
Expand Down
3 changes: 2 additions & 1 deletion QRCoder.Core/Renderers/PostscriptQRCode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
namespace QRCoder.Core.Renderers
{
/// <summary>
/// PostscriptQRCode
/// Renders a QR code as a Postscript or EPS (Encapsulated PostScript) string.
/// Suitable for high-quality print output and vector graphics workflows.
/// </summary>
public class PostscriptQRCode : AbstractQRCode
{
Expand Down
Loading
Loading