Skip to main content

handwriting-generator

Render text as a natural-looking handwriting image (PNG) from the command line or as a Python library. It draws a handwriting-style font glyph-by-glyph and applies subtle, seeded per-glyph randomization (baseline wander, slight rotation, size wobble) so the result looks hand-written instead of typeset.

This is a font-rendering approach — not machine learning. It runs fully offline: no network access or API keys at runtime. (A font is downloaded once at build time and committed into the package.)

Install

pip install .
# or, for development with tests:
pip install -e ".[test]"

Runtime dependency: Pillow.

CLI

Two equivalent entry points are installed: handwriting-generator and the shorter handwrite.

# Simple
handwriting-generator "Dear John, I hope this letter finds you well." -o note.png

# From a file (use '-' for stdin)
handwriting-generator --input letter.txt -o letter.png

# Messy notebook style, reproducible
handwrite "Meeting notes" --paper lined --jitter 1.8 --seed 42 -o notes.png

# Neat, narrow column, custom ink color
handwrite "Tidy and straight" --jitter 0 --width 600 --color "#1a1a8a" -o tidy.png

Flags

Flag Default Meaning
TEXT (positional) — Text to render (omit when using --input).
--input, -i — Read text from a file (- = stdin).
--output, -o handwriting.png Output PNG path.
--font bundled Shadows Into Light Path to a .ttf/.otf font.
--size 48 Font size in points.
--color #1a1a8a Ink color (#hex, name, or rgb(...)).
--width 1000 Word-wrap column width in px (0 disables wrapping).
--jitter 1.0 Messiness. 0 = neat; higher = messier.
--line-spacing 1.0 Line-height multiplier.
--paper blank blank, lined, or none (transparent).
--margin 40 Padding around the text, in px.
--seed none RNG seed; same text+seed+settings ⇒ byte-identical PNG.

Long text is word-wrapped to --width, and the image grows taller to fit all lines.

Library

from handwriting_generator import HandwritingRenderer, RenderConfig, render_text

# One-shot helper
render_text("Hello, world!", "hello.png", paper="lined", jitter=1.2, seed=7)

# Or keep a configured renderer
cfg = RenderConfig(size=56, color="#222222", width=800, jitter=0.8, seed=1)
renderer = HandwritingRenderer(cfg)
img = renderer.render("Reusable renderer")   # a PIL RGBA Image
renderer.save("Reusable renderer", "out.png")

Determinism

Pass --seed (CLI) or seed= (library) to make output reproducible: the same text, seed, and settings always produce a byte-identical PNG. Without a seed, the jitter is randomized on each run.

Licensing

  • Code: MIT (see LICENSE).
  • Bundled font: Shadows Into Light by Kimberly Geswein is licensed under the SIL Open Font License, Version 1.1. Its full license text ships with the package at handwriting_generator/fonts/OFL.txt. The OFL is not the same as the MIT license that covers the code; it governs the font file only. You may swap in any other font with --font.

Metadata

Release files for handwriting-generator 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for handwriting-generator 0.1.0
File Size Uploaded Provenance
handwriting_generator-0.1.0.tar.gz 52.2 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for handwriting-generator 0.1.0
File Interpreter ABI Platform
handwriting_generator-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 101.2 kB

Release files / handwriting_generator-0.1.0.tar.gz

Download URL handwriting_generator-0.1.0.tar.gz
Size 52.2 kB
Tags Source
SHA-256 checksum
How to use checksums
71f1ba4a431bf62818237af74ef89feeb8b264f8a0fc1044e0d55ad605dd4d90
BLAKE2b-256 checksum
How to use checksums
899a2a3ed004d0d2a1f0aeb75e87f650c8b9e5d09f561b35167d6a85971673c9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.13

Release files / handwriting_generator-0.1.0-py3-none-any.whl

Download URL handwriting_generator-0.1.0-py3-none-any.whl
Size 49.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
b94d0f4c220605661bb87f6f63fb3aa19475bf45239abf8c74b36c138d877951
BLAKE2b-256 checksum
How to use checksums
a00e17628791d5650d175325f2885ae996dcd36eb74dfd0b9d250747c55bca7d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.13

Security for handwriting-generator 0.1.0

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.

Release history Release notifications | RSS feed

This release

0.1.0 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