Skip to main content

qrforge

Python Version License Tests Dependencies

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 qrforge failing on Python 3.8–3.11. gradient.py svg_paint had 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 builtin dict[...] annotation with typing.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)

Source distribution for qrforge 1.0.1
File Size Uploaded Provenance
qrforge-1.0.1.tar.gz 68.5 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for qrforge 1.0.1
File Interpreter ABI Platform
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.

Release history Release notifications | RSS feed

This release

1.0.1 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page