qrforge
An open-source Python library for generating and art-directing QR codes: custom module shapes, gradients, shaders, logos, image textures, backgrounds and shadows — output to PNG, SVG, PDF, terminal ANSI, ASCII or Pillow.
qrforge implements the full QR encoding pipeline (modes, Reed–Solomon error correction, masking, versions 1–40) from scratch against the standard library. There are zero required dependencies; Pillow is used only for non-PNG image formats, PIL images, or JPEG/GIF/WEBP logos. PNG reading/writing is built in.
Changelog:
v1.0.1
- Fix
import qrforgefailing on Python 3.8–3.11.gradient.pysvg_painthad a backslash inside an f-string expression, which is only legal on 3.12+. The stop-opacity attribute is now built outside the f-string. Adds a regression test for translucent gradient stops. gf.py: replace builtindict[...]annotation withtyping.Dict(3.8-safe spelling).- README: explicitly states that Python 3.8–3.10 are declared as supported but not tested; the test suite was only run on Python 3.11.
Installation
You can install qrforge using pip:
pip install qrforge
Or from source:
pip install . # or copy the qrforge/ folder next to your code
pip install pillow # optional, only for non-PNG formats / PIL images
Supported Python Versions
- Python 3.8 / 3.9 / 3.10 / 3.11 / 3.12 (or later)
- Testing status: the test suite was run on Python 3.11 only. Python 3.8, 3.9 and 3.10 are declared as supported but have not been tested; the code was checked statically for 3.8-compatible syntax and library usage. Please report any problems on those versions.
Features
- Correct encoder – versions 1–40, EC levels L/M/Q/H, optimal numeric/alphanumeric/byte segmentation, automatic mask selection.
- Shapes – square, rounded, dot, diamond, hexagon, star, cross, squircle, leaf, heart etc. plus random-per-module mixes and your own SDF shapes.
- Gradients & colours – hex /
rgb()/hsl()/ CSS names; linear, radial and conic gradients for modules, eyes and background. - Shaders – grain, glow, wave, twist, glitch, chromatic aberration, halftone, duotone, scanlines, vignette etc. plus custom Python or one-line expression shaders.
- Logos & textures – auto knockout zone, round/clip the logo, logo background, stroke, rotation, opacity; paint any image inside the modules.
- Outputs – PNG (pure-Python codec), SVG (tiny vector), PDF (vector), terminal ANSI, ASCII, Pillow, HTML.
- 22 ready-made presets and a CLI.
Usage
Quickstart
import qrforge
qrforge.save("https://example.com", "code.png", "neon", scale=12)
qr = qrforge.QR("hello", ec="h")
qr.use_style(module_shape="dot", fg=["#ff0080", "#7928ca"], logo="logo.png")
qr.save("poster.png", scale=14)
qr.save("poster.svg")
print(qr.terminal())
Colours & gradients
qr.use_style(fg=["#ff9a3c", "#ff4d6d", "#7b2ff7"]) # linear
qr.use_style(fg={"kind":"radial", "colors":["#fff","#1f6feb"]})
qr.use_style(fg={"kind":"conic", "colors":["#ff71ce","#01cdfe","#05ffa1"]})
Shapes & eyes
qr.use_style(module_shape=["dot","star","hexagon"], seed=3, module_jitter=0.2,
eye_shape="rounded", eye_dot_shape="circle")
@qrforge.shape("wave") # register a custom shape (SDF in module units)
def wave(x, y, radius=0.0):
import math
return qrforge.shapes.sd_circle(x, y + 0.08*math.sin(x*9), 0.5)
Shaders
qr.use_style(shaders=["wave:amplitude=4,wavelength=36", "chromatic:offset=2"])
@qrforge.shader # custom per-pixel shader
def heat(x, y, color, ctx):
return color.mix("#ff4400", ctx.uv(x, y)[1])
Logos
qr.use_style(logo="logo.png", logo_size=0.26, logo_shape="rounded",
logo_radius=0.4, logo_bg="#ffffff", logo_stroke=("#000", 0.2),
logo_rotation=0, logo_opacity=1.0)
Presets & overrides
Any preset's defaults (colours, shaders, etc.) can be overridden:
qrforge.save("hi", "out.png", "neon", fg="#00ff88", scale=12)
qrforge.presets.get("sunset", bg="#000000")
Presets: classic dots rounded soft confetti neon sunset blueprint brutal vapor film halftone gold ice leaf circuit retro glitch minimal badge starry cross.
Correctness
qr.verify() # decodes the symbol again
from qrforge.verify import decode
CLI
python -m qrforge "https://example.com" -o out.png -p neon -s 12 -e h
python -m qrforge "hi" --terminal
python -m qrforge --list-presets --list-shapes --list-shaders
Testing
python -m pytest tests -q
The suite cross-checks the spec tables, Reed–Solomon correction, optimal segmentation against a brute-force reference, the PNG codec against Pillow, and re-rasterises every preset + the SVG geometry to prove each one still scans.
Contributing
Contributions are welcome! See CONTRIBUTING.md. If you encounter any issues or have an edge use case, please open an issue using the templates in .github/ISSUE_TEMPLATE.
License
qrforge is released under the terms of the MIT License (Modified). Please see the LICENSE.md file for the full text.
Metadata
Release files for qrforge 1.0.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| qrforge-1.0.1.tar.gz | 68.5 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| qrforge-1.0.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 137.4 kB
Release files / qrforge-1.0.1.tar.gz
| Download URL | qrforge-1.0.1.tar.gz |
|---|---|
| Size | 68.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
029bea1427587a7785ca8f65a8aac5eb9586f66b40bc0a1ba454b210bdf02035
|
|
BLAKE2b-256 checksum How to use checksums |
e1b2209c0536d1ada373207c069eca6681775b7b1e5e7f13e0ec92620f501290
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.9.25
|
Release files / qrforge-1.0.1-py3-none-any.whl
| Download URL | qrforge-1.0.1-py3-none-any.whl |
|---|---|
| Size | 68.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
c6d2268b6768d27c4fc6c2048719277769fb4bf6e84b4bee0c5a55fe8fce166d
|
|
BLAKE2b-256 checksum How to use checksums |
54d27d9fba5d8c7b38c85de248bc1f47052ca048502a6ef4bbaf5a78ad217de0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.9.25
|
Security for qrforge 1.0.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.