Docs 1.24.0: Barcodes
Download PDF Changelog

This is the manual for PdfPecker 1.24.0. Read it for the latest version, 1.25.0.

Barcodes

Changed in 1.24.0: Reading barcodes.

Barcode draws QR codes, EPC payment QR codes, Code 128 and EAN-13 barcodes as SVG markup for your HTML template. The SVG stays vector graphics in the PDF, so the code scans at any print size. Like the rest of PdfPecker it needs no other package.

// Inline SVG in the template
string qr = Barcode.QrCode("https://example.com/invoice/1042");
string html = $"<p>Scan to pay online:</p>{qr}";

// Or as an image, a CSS background or a Markdown image
string src = Barcode.ToDataUri(Barcode.Ean13("590123412345"));
string img = $"<img src=\"{src}\" style=\"width:40mm\">";

// Code 128 for order numbers, shipping labels and other ASCII text
string label = Barcode.Code128("ORDER-2026-1042", new BarcodeOptions { Height = 40, ShowText = false });

QR codes

Barcode.QrCode picks the smallest QR code (versions 1 to 40) that holds the text at the chosen error correction. Digits only and upper-case alphanumeric text are packed densely, and anything else is stored as UTF-8, up to 2,953 bytes at the lowest level. BarcodeOptions.ErrorCorrection is Low (about 7 percent of the code may be damaged), Medium (15 percent, the default), Quartile (25 percent) or High (30 percent, for codes printed small or with a logo on top). Text that does not fit throws ArgumentException.

EPC payment QR codes

Barcode.EpcQrCode draws the European Payments Council's QR code for a euro credit transfer, also called GiroCode, which banking apps read to fill in the payment. Set Name and Iban on an EpcPayment; the rest is optional.

string pay = Barcode.EpcQrCode(new EpcPayment
{
    Name = "Example Ltd",
    Iban = "DE89 3704 0044 0532 0130 00",
    Amount = 129.95m,
    Text = "Invoice 1042",
});

The payment follows guideline EPC069-12 (version 002, UTF-8) and is checked before drawing: the IBAN's check digits, an 8 or 11 character Bic, an Amount from 0.01 to 999,999,999.99 with at most two decimals (or null to let the payer enter it), a four-letter Purpose code, and either a structured creditor Reference (ISO 11649, "RF...") or a Text of up to 140 characters, not both. Information is a note shown to the payer. A field that is missing, too long or invalid throws ArgumentException. The code always uses error correction level M, as the guideline requires. ToPayload() returns the text the code holds.

Swiss QR-bills

Barcode.SwissQrCode draws the QR code of a Swiss QR-bill, with the Swiss cross in the middle, from a SwissQrBill: the CH or LI IBAN of the creditor, structured addresses, the amount and currency (CHF or EUR), and a QR reference with its check digit for a QR-IBAN, or an ISO 11649 creditor reference or none for an ordinary IBAN. Every field is checked against the standard (guidelines version 2.3), and a wrong one throws ArgumentException; ToPayload() gives the text inside the code.

string qr = Barcode.SwissQrCode(new SwissQrBill
{
    Account = "CH58 0079 1123 0008 8901 2",
    Creditor = new SwissQrAddress { Name = "Robert Schneider AG", Street = "Rue du Lac", HouseNumber = "1268",
                                    PostalCode = "2501", Town = "Biel" },
    Amount = 1949.75m,
    Reference = "RF18539007547034",
});

PdfPecker.Fluent lays out the whole payment part with its receipt with SwissQrBill.

Data Matrix

Barcode.DataMatrix draws an ECC 200 Data Matrix code in the smallest of the 24 square sizes that holds the text, the usual code for small labels, where a QR code of the same data is larger. Barcode.Gs1DataMatrix takes a GS1 element string with the application identifiers in parentheses, as shipping and pharmaceutical labels use:

string label = Barcode.Gs1DataMatrix("(01)09501101530003(17)261231(10)AB-123");

Code 128 and EAN-13

Barcode.Code128 takes 1 to 1,000 ASCII characters and packs runs of digits two to a symbol. Barcode.Ean13 takes 12 digits and adds the check digit, or 13 digits with a correct check digit, and draws the retail barcode with its guard bars. Both print the text below the bars unless ShowText is false.

Options

BarcodeOptions sets:

  • ModuleSize: the width of the narrowest bar or one QR square in CSS pixels, which sets the SVG's size. The default is 3 for QR codes and 1.5 for barcodes. CSS width on the SVG or image scales it too.
  • Height: the bar height of Code 128 and EAN-13 in CSS pixels; the default is 60 modules.
  • QuietZone: the blank margin scanners need around the code (4 modules for QR, 10 for Code 128, 11 and 7 for EAN-13). On by default; turn it off only when the layout leaves that space.
  • Color and Background: CSS colours, #000 on #fff by default. Set Background to null for none, but keep the code dark on light, since scanners need the contrast.

Reading barcodes New in 1.24.0

Barcode.Read reads the QR codes, Data Matrix codes (square, rectangular and the DMRE sizes), Code 128 and EAN-13 barcodes in a PNG, JPEG, GIF, WebP, BMP or TIFF image, and PdfBarcodes.Find those on the pages of a PDF, whether they are drawn as vectors, embedded as images or scanned. Codes may be turned, tilted, mirrored or light on dark.

foreach (BarcodeResult code in Barcode.ReadFile("delivery-note.png"))
    Console.WriteLine($"{code.Format}: {code.Text}");

// Every code on the pages of a PDF, with its page and position in points from the top left
foreach (BarcodeResult code in PdfBarcodes.Find(pdfBytes, new PdfBarcodeOptions { Formats = BarcodeFormat.QrCode }))
    if (code.EpcPayment is { } payment)
        Console.WriteLine($"Page {code.PageNumber}: {payment.Amount} EUR to {payment.Iban}");

Each BarcodeResult has its Format, its Text and Bytes, its Corners and bounding box (in pixels for an image, in points on the page for a PDF), IsGs1 for GS1 data, and the payment of an EPC or Swiss QR-bill code parsed back into EpcPayment or SwissQrBill. BarcodeReaderOptions and PdfBarcodeOptions choose the Formats, whether to TryInverted light-on-dark codes and how many codes to return; PdfBarcodeOptions also takes a Password, Pages and the Dpi pages are rendered at (300 by default). Images and PDFs are handled as untrusted input, with a bounded amount of work per image.