> For the complete documentation index, see [llms.txt](https://infinitode-docs.gitbook.io/documentation/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://infinitode-docs.gitbook.io/documentation/package-documentation/qrforge-package-documentation.md).

# qrforge Package Documentation

Package documentation for qrforge, an open-source Python library for generating and art-directing QR codes with custom shapes, gradients, shaders, logos and textures. Zero required dependencies.

![Python Version](https://img.shields.io/badge/python-3.8+-blue.svg) ![PyPI Version](https://img.shields.io/pypi/v/qrforge) ![Downloads](https://pepy.tech/badge/qrforge) ![License](https://img.shields.io/badge/license-MIT-brightgreen.svg) ![Dependencies](https://img.shields.io/badge/dependencies-0%20\(required\)-blue.svg)

qrforge is an open-source Python library for **generating and art-directing QR codes**: custom module shapes, gradients, shaders, logos, image textures, backgrounds and shadows — with output to PNG, SVG, PDF, terminal ANSI, ASCII, HTML or Pillow.

It 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](https://pillow.readthedocs.io) is used only for non-PNG image formats, Pillow images, or JPEG/GIF/WEBP logos. PNG reading and writing is built in.

{% hint style="info" %}
**qrforge** is intended to produce both *correct* and *beautiful* QR codes. Every rendered symbol is round-trip verified by a bundled decoder, and the test-suite re-rasterises the SVG geometry to prove it reproduces the matrix — so "pretty" never comes at the cost of "scannable".
{% endhint %}

***

## Changelog

* **1.0.1 (Latest)**: Compatibility and documentation fixes — no API, style or rendering changes.
  * **`import qrforge` no longer fails on Python 3.8–3.11.** `Gradient.svg_paint()` built the SVG `stop-opacity` attribute with a backslash inside an f-string expression, which is only legal from Python 3.12 onwards; on older interpreters the module raised `SyntaxError: f-string expression part cannot include a backslash` at import time. The attribute is now assembled outside the f-string, so translucent gradient stops render correctly everywhere. A regression test (`test_gradient_svg_stop_opacity_for_translucent_stops`) covers the translucent-stop case.
  * **`gf.py` uses `typing.Dict`** instead of the built-in `dict[int, List[int]]` annotation, which is not subscriptable before Python 3.9.
  * **Testing status is now stated explicitly**: the suite is run on Python 3.11; Python 3.8, 3.9 and 3.10 are declared as supported but are not exercised by CI. See [Supported Python versions](#supported-python-versions).
  * Everything else — styles, shaders, presets, outputs and the CLI — is unchanged from 1.0.0, so every example in these docs still applies. The [gallery](/documentation/package-documentation/qrforge-package-documentation/qrforge-gallery.md) was rendered with 1.0.1.
  * Cosmetic quirk carried over from 1.0.0: the 1.0.1 distribution still reports `1.0.0` from `qrforge.__version__` (and therefore from `python -m qrforge --version-info`), because only the version in `setup.py` is replaced by the release workflow. Check `pip show qrforge` to see the installed release.
* **1.0.0**: Initial release.
  * Full QR encoder: versions 1–40, error correction levels L / M / Q / H, optimal numeric/alphanumeric/byte segmentation and automatic mask selection.
  * 18 module shapes (square, rounded, dot, diamond, hexagon, star, cross, squircle, leaf, heart …) plus random per-module mixes and your own SDF shapes.
  * Colours and gradients: hex, `rgb()`, `hsl()` and CSS names, with linear, radial and conic gradients for modules, eyes and background.
  * 20 shaders (grain, glow, wave, twist, glitch, chromatic aberration, halftone, duotone, scanlines, vignette …) plus custom Python or one-line expression shaders.
  * Logos and textures: automatic knockout zone, round/clip the logo, logo background, stroke, rotation, opacity — or paint any image inside the modules.
  * Outputs: PNG (pure-Python codec), SVG (tiny vector), PDF (vector), terminal ANSI, ASCII, HTML and Pillow.
  * 22 ready-made presets and a command line interface.
  * A bundled QR *decoder* so `qr.verify()` can prove a styled symbol still scans.

### Known limitations

* The style options `invert`, `eye_padding` and `texture_global` are accepted by `Style` but are not applied by any renderer yet.
* `logo_position` is honoured by the raster renderer only; SVG output always centres the logo.
* `scanlines`, `outline` and `stroke` shaders apply to SVG output but not to raster output, while `twist`, `swirl`, `bulge`, `glitch` and `halftone` are raster-only.
* Shader specs given as a `("name", {"param": value})` tuple fail with a `TypeError` — pass `"name:param=value"` strings, `Shader` objects or callables instead.
* Rendering straight to `.jpg` / `.jpeg` fails because the rendered buffer is RGBA (`OSError: cannot write mode RGBA as JPEG`); convert to RGB first: `qr.to_pil().convert("RGB").save("out.jpg")`.
* `qrforge.__version__` reports `1.0.0` even on the 1.0.1 release, because only `setup.py` receives the release tag during publishing. Use `pip show qrforge` to confirm the installed version.
* The one-line shortcuts (`qrforge.save`, `png`, `svg`, `terminal`, `make`) forward every keyword to `Style`, so encoding options such as `ec`, `version` and `mask` are rejected with `StyleError`. Build a `qrforge.QR(data, ec="h")` when you need them.

***

## Installation

You can install qrforge using pip:

```bash
pip install qrforge
```

Or from source:

```bash
pip install .            # or copy the qrforge/ folder next to your code
pip install pillow       # optional, only for non-PNG formats / PIL images
```

{% hint style="info" %}
`qrforge` has no hard dependencies. Install `pillow` only when you need JPEG/WebP/BMP/GIF/TIFF output, Pillow `Image` objects, or non-PNG logos and textures.
{% endhint %}

## Supported Python versions

* Python 3.8 / 3.9 / 3.10 / 3.11 / 3.12 (or later)
* **Testing status:** the test suite is run on **Python 3.11 only**. Python 3.8, 3.9 and 3.10 are declared as supported and the code is kept 3.8-compatible, but those versions are not exercised — 1.0.1 fixed the import error that made them unusable in 1.0.0. Please report any problems on those versions.

Please make sure you are using a supported Python version before installing qrforge.

***

## 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.

***

## Gallery

Real output, not mock-ups — every image below is a PNG written by qrforge 1.0.1 and verified as scannable. The [full gallery](/documentation/package-documentation/qrforge-package-documentation/qrforge-gallery.md) shows all 22 presets plus gradients, custom shapes, eyes, shaders, logos, textures, cards and transparency, with the code that produced each one.

|                                                                                                          `classic`                                                                                                          |                                                                                                         `dots`                                                                                                        |                                                                                                         `neon`                                                                                                        |
| :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
| ![classic preset](https://3257474019-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFbya6xCbCOMkITeJrPUp%2Fuploads%2Fgit-blob-5346e4c84349fd738a8c47578c806ba98163539e%2Fpreset-classic.png?alt=media) | ![dots preset](https://3257474019-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFbya6xCbCOMkITeJrPUp%2Fuploads%2Fgit-blob-0814f07ace319ce976e65e57a35494ff46c9e2ed%2Fpreset-dots.png?alt=media) | ![neon preset](https://3257474019-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFbya6xCbCOMkITeJrPUp%2Fuploads%2Fgit-blob-afbcbd971cac685dea8055d7e7d9d5c9468e6afa%2Fpreset-neon.png?alt=media) |

|                                                                                                          `sunset`                                                                                                         |                                                                                                         `vapor`                                                                                                         |                                                                                                         `gold`                                                                                                        |
| :-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
| ![sunset preset](https://3257474019-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFbya6xCbCOMkITeJrPUp%2Fuploads%2Fgit-blob-b6cbd80282341baa657e9191a84afbda927e02a2%2Fpreset-sunset.png?alt=media) | ![vapor preset](https://3257474019-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFbya6xCbCOMkITeJrPUp%2Fuploads%2Fgit-blob-2c99faa24318055c43c6d1bf50e4aad1c2bc23fc%2Fpreset-vapor.png?alt=media) | ![gold preset](https://3257474019-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFbya6xCbCOMkITeJrPUp%2Fuploads%2Fgit-blob-9ba420d7cc8b1cb76493850a139c96bf0ee5ef08%2Fpreset-gold.png?alt=media) |

|                                                                                                         `leaf`                                                                                                        |                                                                                                         `badge`                                                                                                         |                                                                                                          `starry`                                                                                                         |
| :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
| ![leaf preset](https://3257474019-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFbya6xCbCOMkITeJrPUp%2Fuploads%2Fgit-blob-968de4814c11bb8c66c938e77afb58925935bc18%2Fpreset-leaf.png?alt=media) | ![badge preset](https://3257474019-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFbya6xCbCOMkITeJrPUp%2Fuploads%2Fgit-blob-59747400aeb2780b754bebc67e2037ae670749f6%2Fpreset-badge.png?alt=media) | ![starry preset](https://3257474019-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFbya6xCbCOMkITeJrPUp%2Fuploads%2Fgit-blob-2685e5ed1458a1da4237b18001c15ba4cf5622d2%2Fpreset-starry.png?alt=media) |

|                                                                                                              Logo knockout                                                                                                              |                                                                                                                Image texture                                                                                                                |                                                                                                                  Card & shadow                                                                                                                  |
| :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
| ![QR code with a logo knockout](https://3257474019-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFbya6xCbCOMkITeJrPUp%2Fuploads%2Fgit-blob-785c9e875aa88ccee42b9917eeea3a27c7d1dec8%2Ffeature-logo.png?alt=media) | ![QR code with an image texture](https://3257474019-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFbya6xCbCOMkITeJrPUp%2Fuploads%2Fgit-blob-794c1e86c2add987dffbae766a62003cba445ead%2Ffeature-texture.png?alt=media) | ![QR code on a card with a drop shadow](https://3257474019-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFbya6xCbCOMkITeJrPUp%2Fuploads%2Fgit-blob-dc859415a3ccfd803c92281ec7acc0868f1b013b%2Ffeature-card.png?alt=media) |

[**Open the full gallery →**](/documentation/package-documentation/qrforge-package-documentation/qrforge-gallery.md) — all 22 presets, plus gradients, custom shapes, eyes, shaders, logos, textures, cards and transparency, each with the code that rendered it.

***

## Example usage

### Quickstart

```python
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

```python
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

```python
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

```python
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

```python
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:

```python
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

```python
qr.verify()                      # decodes the symbol again
from qrforge.verify import decode
```

Symbols are round-trip verified, so you can check any styling decision before shipping it. Verify logo and shader choices at small scale and keep the error correction level high (`ec="h"`) when you cover modules.

***

## Command line

```bash
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
```

{% hint style="warning" %}
Error correction levels passed to the CLI must be uppercase (`L`, `M`, `Q` or `H`). The installed console script `qrforge` accepts the same options as `python -m qrforge`.
{% endhint %}

***

## Testing

From a clone of the [repository](https://github.com/infinitode/qrforge):

```bash
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.

***

## Learn more

* [qrforge Gallery](/documentation/package-documentation/qrforge-package-documentation/qrforge-gallery.md) for every preset and feature rendered as real, verified images.
* [qrforge Usage Examples](/documentation/package-documentation/qrforge-package-documentation/qrforge-usage-examples.md) for complete, runnable recipes.
* [qrforge Reference](/documentation/package-documentation/qrforge-package-documentation/qrforge-reference.md) for the full API.
* [API & Functions](/documentation/package-documentation/qrforge-package-documentation/qrforge-reference/qrforge-api-functions.md) — classes and functions.
* [Style Options](/documentation/package-documentation/qrforge-package-documentation/qrforge-reference/qrforge-style-options.md) — every style knob.
* [Shapes & Shaders](/documentation/package-documentation/qrforge-package-documentation/qrforge-reference/qrforge-shapes-and-shaders.md) — shapes, shaders and custom effects.
* [Presets & Outputs](/documentation/package-documentation/qrforge-package-documentation/qrforge-reference/qrforge-presets-and-outputs.md) — presets, file formats, CLI and helpers.

Source code, issues and contribution guidelines live in the [Infinitode/qrforge GitHub repository](https://github.com/infinitode/qrforge); the package is published on [PyPI](https://pypi.org/project/qrforge/).

***

## Contributing

Contributions are welcome! See [CONTRIBUTING.md](https://github.com/infinitode/qrforge/blob/main/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](https://github.com/infinitode/qrforge/blob/main/LICENSE.md) file for the full text.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://infinitode-docs.gitbook.io/documentation/package-documentation/qrforge-package-documentation.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
