Skip to content

QR Codes & Barcodes

Generate QR codes and 1D barcodes directly as PDF documents, as standalone PNG/SVG images, or place them onto pages of an existing PDF. Barcode generation is behind a feature flag to keep the core library lightweight.

Binding coverage. There are two distinct barcode surfaces:

  1. One-shot PDF constructors (Pdf::from_qrcode / Pdf::from_barcode) and the low-level BarcodeGenerator — exposed in Rust only.
  2. The barcode-image handle family (generate_qr_code, generate_barcode, add_barcode_to_page) backed by the C ABI pdf_generate_qr_code / pdf_generate_barcode / pdf_add_barcode_to_page functions — exposed in Swift, Go, and C#, and callable directly from C/C++ over FFI.
  3. SVG generators (generate_qr_svg / generate_barcode_svg) — exposed in Python and Rust.

Each method below is labelled with the languages that actually expose it. Do not assume a method exists in a binding where it is not shown.

Requires feature flag: barcodes

# Cargo.toml
[dependencies]
pdf_oxide = { version = "0.3", features = ["barcodes"] }

How do I generate a QR code as a PDF?

The fastest path in Rust is the one-shot Pdf::from_qrcode constructor. pdf_oxide writes the QR code into a single-page PDF that you can save directly.

Rust:

use pdf_oxide::api::Pdf;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // QR code (300px) -> single-page PDF
    let pdf = Pdf::from_qrcode("https://example.com")?;
    pdf.save("qrcode.pdf")?;

    // 1D barcode -> single-page PDF
    use pdf_oxide::writer::barcode::BarcodeType;
    let pdf = Pdf::from_barcode(BarcodeType::Code128, "ABC-12345")?;
    pdf.save("barcode.pdf")?;
    Ok(())
}

How do I generate a barcode image (PNG/SVG) instead of a PDF?

When you want the encoded glyph as an image — to embed in an existing document, ship to a web frontend, or print on a label — use the image-handle family or the SVG generators. These are the canonical method names: generate_qr_code and generate_barcode (the older generate_qr / generate_code names are not part of the public surface).

Swift (BarcodeImage.generateQrCode, BarcodeImage.generateBarcode):

import PdfOxide

// QR code. errorCorrection: 0=L 1=M 2=Q 3=H. sizePx: module-grid pixel size.
let qr = try BarcodeImage.generateQrCode("https://example.com",
                                         errorCorrection: 1, sizePx: 256)
let pngBytes = try qr.imagePng(sizePx: 256)   // [UInt8]
let svg      = try qr.svg(sizePx: 256)        // String
qr.close()

// 1D barcode. format: 0=Code128 1=Code39 2=EAN13 3=EAN8 4=UPCA 5=ITF 6=Code93 7=Codabar.
let bc = try BarcodeImage.generateBarcode("5901234123457", format: 2, sizePx: 256)
let barcodePng = try bc.imagePng(sizePx: 256)
bc.close()

Go (GenerateQRCode, GenerateBarcode):

package main

import (
	"os"

	pdfoxide "github.com/yfedoseev/pdf_oxide/go"
)

func main() {
	// QR code. errorCorrection: 0=Low 1=Medium 2=Quartile 3=High.
	qr, err := pdfoxide.GenerateQRCode("https://example.com", 1, 256)
	if err != nil {
		panic(err)
	}
	defer qr.Close()
	svg, _ := qr.SVGData()
	_ = os.WriteFile("qr.svg", []byte(svg), 0o644)

	// 1D barcode. format: 0=Code128 1=Code39 2=EAN13 3=EAN8 4=UPCA 5=ITF 6=Code93 7=Codabar.
	bc, err := pdfoxide.GenerateBarcode("5901234123457", 2, 300)
	if err != nil {
		panic(err)
	}
	defer bc.Close()
	png, _ := bc.PNGData()
	_ = os.WriteFile("ean13.png", png, 0o644)
}

C# (Barcode.GenerateQrCode, Barcode.Generate):

using PdfOxide;

// QR code. errorCorrection: 0=L 1=M 2=Q 3=H. sizePx default 300.
using var qr = Barcode.GenerateQrCode("https://example.com", errorCorrection: 1, sizePx: 256);
byte[] qrPng = qr.ToPng(256);
string qrSvg = qr.ToSvg();

// 1D barcode. BarcodeFormat: Code128, Code39, Ean13, Ean8, UpcA, Itf.
using var bc = Barcode.Generate("5901234123457", BarcodeFormat.Ean13, sizePx: 300);
byte[] eanPng = bc.ToPng(300);

Python (generate_qr_svg, generate_barcode_svg — SVG only):

import pdf_oxide

# QR code SVG. error_correction: 0=Low, 1=Medium, 2=Quartile, 3=High. size in px.
qr_svg = pdf_oxide.generate_qr_svg("https://example.com", 1, 256)
with open("qr.svg", "w") as f:
    f.write(qr_svg)

# 1D barcode SVG. barcode_type: 0=Code128, 1=Code39, 2=EAN13, 3=EAN8,
#                                4=UPCA, 5=ITF, 6=Code93, 7=Codabar.
ean_svg = pdf_oxide.generate_barcode_svg(2, "5901234123457")
with open("ean13.svg", "w") as f:
    f.write(ean_svg)

How do I add a barcode to an existing PDF page?

Use add_barcode_to_page to place a generated barcode image onto a (0-based) page of a DocumentEditor at a given position and size, then save. This is exposed idiomatically in Swift as DocumentEditor.addBarcodeToPage and directly over the C ABI as pdf_add_barcode_to_page. The image-handle family it depends on is not wrapped on the Go/C# editor classes, so use Swift (or call the C ABI from C/C++) for in-place placement.

Swift (DocumentEditor.addBarcodeToPage):

import PdfOxide

let editor = try DocumentEditor.openFromBytes(try Data(contentsOf: inputURL).map { $0 })

// Generate the barcode image, then stamp it onto page 0 (PDF user-space points).
let qr = try BarcodeImage.generateQrCode("https://example.com/track/42", sizePx: 128)
try editor.addBarcodeToPage(0, qr, x: 36, y: 36, width: 96, height: 96)

let outBytes = try editor.saveToBytes()
qr.close()
editor.close()

C ABI (pdf_add_barcode_to_page):

#include "pdf_oxide.h"

int err = 0;

// Build a barcode handle (QR shown; use pdf_generate_barcode for 1D).
FfiBarcodeImage *qr = pdf_generate_qr_code("https://example.com/track/42",
                                           /*error_correction=*/1,
                                           /*size_px=*/128, &err);

// Place it on page 0 at (x, y) sized width x height (PDF user-space points).
pdf_add_barcode_to_page(editor, /*page_index=*/0, qr,
                        /*x=*/36.0f, /*y=*/36.0f,
                        /*width=*/96.0f, /*height=*/96.0f, &err);

pdf_barcode_free(qr);

Method signatures

One-shot PDF constructors — Rust only

// QR code, 300px default size:
Pdf::from_qrcode(data: &str) -> Result<Pdf>
Pdf::from_qrcode_with_options(data: &str, options: &QrCodeOptions) -> Result<Pdf>

// 1D barcode, 200x80 default size:
Pdf::from_barcode(barcode_type: BarcodeType, data: &str) -> Result<Pdf>
Pdf::from_barcode_with_options(barcode_type: BarcodeType, data: &str,
                               options: &BarcodeOptions) -> Result<Pdf>

Barcode-image handle family — Swift / Go / C# / C ABI

Language QR generator 1D generator Place on page
Swift BarcodeImage.generateQrCode(_ data:, errorCorrection: Int32 = 1, sizePx: Int32 = 256) BarcodeImage.generateBarcode(_ data:, format: Int32, sizePx: Int32 = 256) DocumentEditor.addBarcodeToPage(_ page:, _ barcode:, x:, y:, width:, height:)
Go GenerateQRCode(data string, errorCorrection int, sizePx int) (*BarcodeImage, error) GenerateBarcode(data string, format int, sizePx int) (*BarcodeImage, error) — (not wrapped on editor)
C# Barcode.GenerateQrCode(string data, int errorCorrection = 1, int sizePx = 300) Barcode.Generate(string data, BarcodeFormat format = Code128, int sizePx = 300) — (not wrapped on editor)
C ABI pdf_generate_qr_code(const char *data, int32_t error_correction, int32_t size_px, int32_t *error_code) pdf_generate_barcode(const char *data, int32_t format, int32_t size_px, int32_t *error_code) pdf_add_barcode_to_page(DocumentEditor *doc, int32_t page_index, const FfiBarcodeImage *barcode, float x, float y, float width, float height, int32_t *error_code)

Once you hold a barcode handle you can read its payload and render it:

Operation Swift Go C# C ABI
PNG bytes imagePng(sizePx:) PNGData() ToPng(sizePx) pdf_barcode_get_image_png
SVG string svg(sizePx:) SVGData() ToSvg() pdf_barcode_get_svg
Decoded data data() SourceData() Data pdf_barcode_get_data
Format code format() Format pdf_barcode_get_format
Free handle close() Close() Dispose() pdf_barcode_free

SVG generators — Python / Rust

# Python free functions (require the barcodes feature in the wheel):
generate_qr_svg(data: str, error_correction: int, size: int) -> str
generate_barcode_svg(barcode_type: int, data: str) -> str

Rust: full API reference

QR code generation

Pdf::from_qrcode(data) — default QR code

Creates a single-page PDF with a 300px QR code.

use pdf_oxide::api::Pdf;

let pdf = Pdf::from_qrcode("https://example.com")?;
pdf.save("qr.pdf")?;

Pdf::from_qrcode_with_options(data, options) — custom QR code

Full control over size, error correction, colors, and quiet zone.

use pdf_oxide::api::Pdf;
use pdf_oxide::writer::barcode::{QrCodeOptions, QrErrorCorrection};

let options = QrCodeOptions::new()
    .size(400)
    .error_correction(QrErrorCorrection::High)
    .quiet_zone(6)
    .foreground(0, 0, 128, 255)          // Navy blue
    .background(255, 255, 255, 255);     // White

let pdf = Pdf::from_qrcode_with_options("https://example.com", &options)?;
pdf.save("custom_qr.pdf")?;

QrCodeOptions — QR configuration

Method Default Description
.size(px) 200 QR code size in pixels
.error_correction(level) Medium Error correction level
.quiet_zone(modules) 4 Border width in modules
.foreground(r, g, b, a) Black (0,0,0,255) Module color (RGBA)
.background(r, g, b, a) White (255,255,255,255) Background color (RGBA)

QrErrorCorrection enum

Variant Recovery Capacity Use Case Integer (FFI)
Low ~7% Maximum data density 0
Medium ~15% General purpose (default) 1
Quartile ~25% Labels that may get damaged 2
High ~30% Industrial / harsh environments 3

1D barcode generation

Pdf::from_barcode(barcode_type, data) — default barcode

Creates a single-page PDF with a barcode using default size (200x80).

use pdf_oxide::api::Pdf;
use pdf_oxide::writer::barcode::BarcodeType;

let pdf = Pdf::from_barcode(BarcodeType::Ean13, "5901234123457")?;
pdf.save("product.pdf")?;

Pdf::from_barcode_with_options(barcode_type, data, options) — custom barcode

Full control over barcode dimensions and colors.

use pdf_oxide::api::Pdf;
use pdf_oxide::writer::barcode::{BarcodeType, BarcodeOptions};

let options = BarcodeOptions::new()
    .width(400)
    .height(120)
    .foreground(0, 0, 0, 255)
    .background(255, 255, 255, 255);

let pdf = Pdf::from_barcode_with_options(
    BarcodeType::Code128,
    "SHIP-2025-00042",
    &options,
)?;
pdf.save("shipping_label.pdf")?;

BarcodeOptions — 1D configuration

Method Default Description
.width(px) 200 Barcode width in pixels
.height(px) 80 Barcode height in pixels
.foreground(r, g, b, a) Black (0,0,0,255) Bar color (RGBA)
.background(r, g, b, a) White (255,255,255,255) Background color (RGBA)
.show_text(bool) false Show human-readable text

BarcodeType enum

Variant Name Data Format Integer (FFI)
Code128 Code 128 Alphanumeric (auto-selects A/B/C) 0
Code39 Code 39 Uppercase alphanumeric + symbols 1
Ean13 EAN-13 13 digits (European Article Number) 2
Ean8 EAN-8 8 digits (compact EAN) 3
UpcA UPC-A 11-12 digits (Universal Product Code) 4
Itf Interleaved 2 of 5 Numeric pairs (even digit count) 5
Code93 Code 93 Alphanumeric (compact) 6
Codabar Codabar Digits + special chars (A-D start/stop) 7

The C ABI pdf_generate_barcode and the Go/Swift/C# wrappers select the symbology by the integer (FFI) column above. The C# BarcodeFormat enum currently exposes Code128Itf (0–5).

Low-level BarcodeGenerator — Rust only

For generating barcode images without creating a full PDF (e.g., to embed in an existing document):

use pdf_oxide::writer::barcode::{BarcodeGenerator, BarcodeType, BarcodeOptions, QrCodeOptions};

// Generate QR code as PNG bytes
let qr_png = BarcodeGenerator::generate_qr(
    "https://example.com",
    &QrCodeOptions::default().size(256),
)?;

// Generate QR code as an SVG string
let qr_svg = BarcodeGenerator::generate_qr_svg(
    "https://example.com",
    &QrCodeOptions::default().size(256),
)?;

// Generate QR code with simple API
let qr_png = BarcodeGenerator::generate_qr_simple("https://example.com", 200)?;

// Generate 1D barcode as PNG bytes
let barcode_png = BarcodeGenerator::generate_1d(
    BarcodeType::Code128,
    "ABC123",
    &BarcodeOptions::default().width(300).height(100),
)?;

// Generate 1D barcode as an SVG string
let barcode_svg = BarcodeGenerator::generate_1d_svg(
    BarcodeType::Code128,
    "ABC123",
    &BarcodeOptions::default(),
)?;

// Convenience methods
let code128_png = BarcodeGenerator::generate_code128("DATA", 200, 80)?;
let ean13_png = BarcodeGenerator::generate_ean13("5901234123457", 200, 80)?;

Using PdfBuilder with barcodes — Rust only

PdfBuilder provides a fluent interface for setting page size and document metadata before generating barcode PDFs.

use pdf_oxide::api::PdfBuilder;
use pdf_oxide::writer::PageSize;
use pdf_oxide::writer::barcode::BarcodeType;

// QR code with custom page size
let pdf = PdfBuilder::new()
    .title("WiFi Access")
    .page_size(PageSize::Custom(300.0, 300.0))
    .from_qrcode("WIFI:T:WPA;S:MyNetwork;P:secret123;;")?;
pdf.save("wifi_qr.pdf")?;

// Barcode with metadata
let pdf = PdfBuilder::new()
    .title("Product Label")
    .author("Warehouse System")
    .from_barcode(BarcodeType::Ean13, "5901234123457")?;
pdf.save("label.pdf")?;

Advanced examples

Shipping label with multiple barcodes (Rust)

use pdf_oxide::writer::barcode::{BarcodeGenerator, QrCodeOptions, QrErrorCorrection};

// Generate barcode images, then embed via the image APIs.
let tracking_barcode = BarcodeGenerator::generate_code128(
    "1Z999AA10123456784",
    300,
    80,
)?;

let qr_bytes = BarcodeGenerator::generate_qr(
    "https://track.example.com/1Z999AA10123456784",
    &QrCodeOptions::new().size(200).error_correction(QrErrorCorrection::Medium),
)?;

// `tracking_barcode` and `qr_bytes` are PNG byte vectors ready to embed.

Batch generate product labels (Rust)

use pdf_oxide::api::Pdf;
use pdf_oxide::writer::barcode::BarcodeType;

let products = vec![
    ("5901234123457", "Widget A"),
    ("4006381333931", "Widget B"),
    ("0012345678905", "Widget C"),
];

for (ean, name) in products {
    let pdf = Pdf::from_barcode(BarcodeType::Ean13, ean)?;
    pdf.save(format!("label_{}.pdf", name.to_lowercase().replace(' ', "_")))?;
}

Batch barcode SVGs (Python)

import pdf_oxide

items = [
    (0, "SHIP-00001"),   # Code128
    (0, "SHIP-00002"),   # Code128
    (2, "5901234123457"),  # EAN-13
    (4, "012345678905"),   # UPC-A
]

for barcode_type, data in items:
    svg = pdf_oxide.generate_barcode_svg(barcode_type, data)
    with open(f"barcode_{data}.svg", "w") as f:
        f.write(svg)

Stamp tracking QR codes onto every label (Swift)

import PdfOxide

let editor = try DocumentEditor.openFromBytes(labelTemplateBytes)
let pageCount = try editor.pageCount()

for page in 0..<pageCount {
    let qr = try BarcodeImage.generateQrCode("https://track.example.com/\(page)", sizePx: 128)
    try editor.addBarcodeToPage(page, qr, x: 420, y: 700, width: 80, height: 80)
    qr.close()
}

let stamped = try editor.saveToBytes()
editor.close()

Feature flag

The barcodes feature pulls in two additional dependencies:

  • barcoders — 1D barcode encoding
  • qrcode — QR code encoding

Without the feature flag, all barcode methods return an error indicating the feature is required.

// Without the barcodes feature enabled:
let result = Pdf::from_qrcode("test");
// Returns Err("QR code generation requires the 'barcodes' feature")

FAQ

Q: The docs mention generate_qr and generate_code — are those the right names? A: No. The canonical public method names are generate_qr_code and generate_barcode (backed by the C ABI pdf_generate_qr_code / pdf_generate_barcode). Inside Rust, the low-level helpers on BarcodeGenerator are generate_qr and generate_1d; those are Rust-internal helpers, not the cross-binding surface.

Q: Can I generate native barcodes from Python or Node? A: Python exposes generate_qr_svg and generate_barcode_svg, which return SVG strings you can embed or rasterize. For PNG handles and in-place page placement, use the Swift, Go, or C# bindings, or call the C ABI directly. Native one-shot PDF constructors (from_qrcode / from_barcode) are Rust-only.

Q: How do I place a barcode at a specific position in an existing PDF? A: Generate the image handle (generate_qr_code / generate_barcode), then call add_barcode_to_page(document, page_index, barcode, x, y, width, height). Coordinates and size are in PDF user-space points and the page index is 0-based. This is wrapped in Swift as DocumentEditor.addBarcodeToPage; from C/C++ call pdf_add_barcode_to_page.

Q: How fast is generation? A: pdf_oxide’s writer is built on the same engine that extracts text at a 0.8ms mean with a 100% pass rate on the benchmark corpus, so encoding a QR or 1D barcode and emitting a page is effectively instantaneous for batch workloads.