Turn a link into print-ready QR code graphics.
Find a file
2026-07-17 13:55:59 +02:00
examples Dateien nach „examples“ hochladen 2026-07-17 13:55:59 +02:00
tests Dateien nach „tests“ hochladen 2026-07-17 13:55:41 +02:00
LICENSE Dateien nach „/“ hochladen 2026-07-17 13:55:06 +02:00
pyproject.toml Dateien nach „/“ hochladen 2026-07-17 13:55:06 +02:00
qrgen.py Dateien nach „/“ hochladen 2026-07-17 13:55:06 +02:00
README.md Dateien nach „/“ hochladen 2026-07-17 13:55:06 +02:00
requirements.txt Dateien nach „/“ hochladen 2026-07-17 13:55:06 +02:00

qrgen

Turn a link into print-ready QR code graphics.

qrgen https://example.org/mueller

This writes output/qr-mueller.svg (vector, ideal for print) and output/qr-mueller.png (roughly 1100 px). Pass several links to get several codes.

An optional batch mode reads a whole CSV and generates one code per row, each pointing to <base-url>/<slug>, plus a links.csv summary of all links. Works for anything that needs scannable links: posters and flyers, product or equipment labels, slides, event signage, or business cards whose short URLs redirect to vCards.

Runs on macOS and Linux with Python 3.9 or newer. Single file, pure Python, one dependency (segno).

Installation

With pipx or uv:

pipx install git+https://code.nerdzoom.media/Marius/qrgen.git
# or
uv tool install git+https://code.nerdzoom.media/Marius/qrgen.git

Or run the script directly without installing:

pip install segno
python3 qrgen.py https://example.org/mueller

For --verify support, add the optional extras:

pipx install "qrgen[verify] @ git+https://code.nerdzoom.media/Marius/qrgen.git"
# or, when running the script directly:
pip install zxing-cpp pillow

Usage

Quick mode, one code per link:

qrgen https://example.org/mueller
qrgen https://example.org/a https://example.org/b --formats png
qrgen https://example.org/mueller --name max-mueller --out codes/

Batch mode from a CSV:

qrgen --csv people.csv --base-url https://example.org --dry-run
qrgen --csv people.csv --base-url https://example.org --verify

All options are listed by qrgen --help:

Option Default Description
URL ... one or more links to encode directly
--csv FILE batch mode: read people from a CSV
--base-url batch mode: URL prefix, the slug is appended
--name derived from URL quick mode: filename stem for a single link
--out output output directory (existing files are overwritten)
--formats svg,png comma-separated subset of svg,png
--error m QR error correction level: l, m, q, h
--png-scale 30 pixels per module (30 gives roughly 1100 px)
--svg-scale 10 SVG units per module
--border 4 quiet zone in modules (QR standard)
--csv-delimiter ; delimiter of the generated links.csv (batch mode)
--dry-run print what would be generated, write nothing
--verify decode every code and compare it with its URL

CSV format (batch mode)

Required column: name. Optional column: slug. All other columns are carried over into the summary links.csv. Comma, semicolon, and tab delimiters are detected automatically; UTF-8 with or without BOM works.

name;slug;role
Erika Mustermann;;Management
Max Mustermann;m-mustermann;Sales
Jürgen Größe;;IT
Ana de la Cruz;de-la-cruz;Design

Slug rules:

  • Without an explicit slug, the last word of the name is used: Erika Mustermann becomes mustermann, Felix Kronlage-Dammers becomes kronlage-dammers. Leading titles like Dr. are irrelevant since only the last word counts.
  • German umlauts are transliterated (Größe becomes groesse), other accents are stripped, everything is lowercased, and remaining characters are reduced to a-z, 0-9, and -.
  • Explicit slugs are needed for multi-part surnames (Ana de la Cruz would otherwise become cruz) and whenever two rows would resolve to the same slug. Colliding slugs abort the run with an error listing the affected rows, so nothing gets overwritten silently.

Output

output/
├── qr-<name>.svg    vector, use this for print layouts
├── qr-<name>.png    raster, roughly 1100 px at default scale
└── links.csv        batch mode only: name, slug, URL, extra columns

In quick mode the filename comes from the last part of the link (.../mueller becomes qr-mueller.svg), or set it with --name. links.csv is written with a semicolon delimiter and a UTF-8 BOM so it opens cleanly in Excel and LibreOffice; change this with --csv-delimiter.

Print notes

  • The quiet zone (4 modules of white space) is already part of every file, no extra margin needed.
  • Recommended minimum print size: about 12 mm edge length.
  • Error correction level m is a good default for short URLs. Use q or h if the codes will be printed very small or on textured material.

Development

pip install -e ".[verify]" pytest
pytest

The Forgejo Actions workflow in .forgejo/workflows/ci.yml runs the test suite plus a smoke test on Python 3.9 and 3.13. It expects a Forgejo runner with a docker label; adjust runs-on if your runner uses different labels.

License

MIT, see LICENSE.