Convert any image into a Paint by Numbers printable PDF
Project description
Strokemap - Paint by Numbers Generator
A Python package and CLI tool to convert any image into a high-quality, print-ready "Paint by Numbers" PDF template.
The generated PDF matches premium standards, split into four cleanly laid-out pages:
- Page 1 - Numbered Template: Light gray outlines with a small, centered index number in each region.
- Page 2 - Clean Outlines: Clean black outlines without any numbers, perfect for clean canvas painting.
- Page 3 - Colorized Preview: A color reference picture showing what the finished painting should look like.
- Page 4 - Color Palette Sheet: A beautifully aligned grid of color swatches showing index numbers, hex codes, paint color blocks, and step-by-step instructions.
Preview
Here is an example of the generator's output using the standard Lenna test image:
| Original Image | Numbered Template (Page 1) | Clean Outlines (Page 2) | Colorized Preview (Page 3) |
|---|---|---|---|
[!NOTE] Image Citation: Lenna (or Lena) is a standard digital image processing test image, originally from the USC-SIPI Image Database. It is widely used for testing image processing algorithms.
Installation
Create a virtual environment and install the package locally:
python3 -m venv .venv
source .venv/bin/activate
pip install -e .
Dependencies
The package relies on the following standard python packages:
numpypillowopencv-pythonscikit-learnreportlabscikit-image
Usage
Command Line Interface
You can convert any image directly from your terminal:
strokemap input.jpg output.pdf --colors 20 --difficulty medium
CLI Options:
image_path(required): Path to the input image file.output_pdf(required): Path where the final PDF should be saved.-c,--colors(optional): Target number of colors (default: 20).-d,--difficulty(optional): Level of region detail (easy,medium,hard) (default:medium).
Python API
You can also use the package programmatically:
from strokemap import PaintByNumbersGenerator, generate_pdf
# 1. Initialize generator with difficulty settings
generator = PaintByNumbersGenerator(difficulty="medium")
# 2. Process image to get templates and palette
numbered_img, clean_img, colorized_img, palette = generator.process("input.jpg", n_colors=20)
# 3. Compile everything into a 4-page A4 PDF
generate_pdf(
output_pdf_path="output.pdf",
numbered_img=numbered_img,
clean_img=clean_img,
colorized_img=colorized_img,
palette=palette,
)
Algorithms Used
- Superpixel Segmentation (SLIC): Uses the Simple Linear Iterative Clustering (SLIC) algorithm to cluster pixels into contiguous, edge-conforming "superpixels". This ensures that the boundaries of regions natively stick to the actual physical boundaries and details in the image (such as eyes, text, and fine lines).
- Color Quantization: Performs K-Means clustering on the average colors of the superpixels in the CIELAB color space. Working in CIELAB space allows color distances to match human perception, resulting in a vibrant and accurate palette.
- Detail Reduction & Region Merging: Small, hard-to-paint micro-regions are intelligently merged into their dominant neighbor using connected components analysis, with thresholds dynamically adjusted by the selected difficulty level.
- Outline Extraction: Computes a pixel-wise transition grid to produce clean, single-pixel outlines.
- Optimal Label Placement: Uses a distance transform (
cv2.distanceTransform) to find the center of the largest inscribed circle within each region, placing number labels at the most readable point.
Authors
- Developer
For additional author and maintainer details, see AUTHORS.md.
Contributors
This project is maintained by the community. See CONTRIBUTORS.md for the current list of contributors and how to get involved.
Contributing
Contributions are welcome! Please read CONTRIBUTING.md before opening an issue or pull request.
Security
If you discover a vulnerability, please do not publish it publicly. Refer to SECURITY.md for our security reporting policy.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file strokemap-0.1.0.tar.gz.
File metadata
- Download URL: strokemap-0.1.0.tar.gz
- Upload date:
- Size: 14.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bbac2ff5454df3dd30ee46f08bf7ed2b7b603384f1ea6ed3c750e433430b1bba
|
|
| MD5 |
582ce4abbd20789a0ae510de61d820c0
|
|
| BLAKE2b-256 |
c10c731d7bd69c2b5381692f9e938ed9bd822b33ee480a8841ec7d83a6221bec
|
Provenance
The following attestation bundles were made for strokemap-0.1.0.tar.gz:
Publisher:
cicd.yml on dipinknair/strokemap
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
strokemap-0.1.0.tar.gz -
Subject digest:
bbac2ff5454df3dd30ee46f08bf7ed2b7b603384f1ea6ed3c750e433430b1bba - Sigstore transparency entry: 1624647383
- Sigstore integration time:
-
Permalink:
dipinknair/strokemap@9d482e2426e43cf9bab832e5b4aa2fd8817566ce -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/dipinknair
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
cicd.yml@9d482e2426e43cf9bab832e5b4aa2fd8817566ce -
Trigger Event:
push
-
Statement type:
File details
Details for the file strokemap-0.1.0-py3-none-any.whl.
File metadata
- Download URL: strokemap-0.1.0-py3-none-any.whl
- Upload date:
- Size: 12.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8cf9e16cfc17f2c743abd5ab764b3758eafbbb41b8a1431e6e8643cab2b97014
|
|
| MD5 |
e0b41dc1a1a436db707e6bae4dfe0815
|
|
| BLAKE2b-256 |
3e0ca020d03b201385e812d0ea017c7c4c490dc07b8af7fd996fc9e6be5b9241
|
Provenance
The following attestation bundles were made for strokemap-0.1.0-py3-none-any.whl:
Publisher:
cicd.yml on dipinknair/strokemap
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
strokemap-0.1.0-py3-none-any.whl -
Subject digest:
8cf9e16cfc17f2c743abd5ab764b3758eafbbb41b8a1431e6e8643cab2b97014 - Sigstore transparency entry: 1624647386
- Sigstore integration time:
-
Permalink:
dipinknair/strokemap@9d482e2426e43cf9bab832e5b4aa2fd8817566ce -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/dipinknair
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
cicd.yml@9d482e2426e43cf9bab832e5b4aa2fd8817566ce -
Trigger Event:
push
-
Statement type: