Open-source web app for photo micro-dot style QR codes (art QR with a background image, corner finders, and short-link mode).
- Generator:
/ - Admin (needs
ADMIN_SECRET):/admin
- Micro-dot art QR —
POST /qr/artblends your photo under a scannable QR pattern. - Short links — optional
https://your-host/s/<code>in the QR; change the destination later in admin without reprinting.
This is deterministic image compositing (Pillow +
qrcode), not an SD/ControlNet pipeline — easy to extend later.
cd QRender
python3 -m venv .venv
source .venv/bin/activatepython -m pip install -U pip
python -m pip install -e .uvicorn app.main:app --reload --host 0.0.0.0 --port 8000- App: http://127.0.0.1:8000/
- OpenAPI: http://127.0.0.1:8000/docs
Static assets (e.g. logo) are served under /static/.
curl http://127.0.0.1:8000/healthcurl -X POST "http://127.0.0.1:8000/qr/art" \
-F "content=https://example.com" \
-F "image=@./your-image.jpg" \
-F "fit_mode=cover" \
-F "cover_zoom=0.5" \
-F "crop_anchor_x=0.5" \
-F "crop_anchor_y=0.5" \
-F "micro_dot_radius_frac=0.22" \
-F "finder_shape=square" \
-F "finder_dark_color=#000000" \
-F "finder_light_color=#ffffff" \
-F "use_short_url=0" \
-F "save_to_admin=0" \
-o art.pngResponse header X-QR-Encoded-Content reflects the string encoded in the QR (after short-link rewrite when enabled).
With “Use short link” in the UI, the QR can encode https://your-host/s/<code> while the real URL is stored in SQLite under data/short_urls.sqlite3:
- The same printed QR can keep working if you change the destination in admin (path
/s/abcunchanged). - Scan counts and timestamps are recorded on each 302 redirect.
Set ADMIN_SECRET, open /admin, paste the token, and manage links or view events.
Production: set PUBLIC_BASE_URL to your public https://… origin so generated QR payloads use the correct host.
Admin API (header X-Admin-Token):
GET /api/admin/linksPATCH /api/admin/links/{code}— JSON{ "target": "https://..." }DELETE /api/admin/links/{code}GET /api/admin/links/{code}/events
Bootstrap .env:
python3 scripts/setup_env.pyThen either:
chmod +x install-docker.sh docker-run.sh
./install-docker.sh
# log out/in for docker group, then:
./docker-run.shor docker compose up --build. SQLite and previews persist in ./data (mounted at /app/data).
If admin token fails after a secret change: restart the app and sign in again on /admin (browser may cache an old token).