caligrama
Dale una imagen y un poema. Te devuelve el poema con la forma de la imagen.
Cada uno de los 40 fotogramas es una llamada a caligrama.dibujar(). El código está en examples/latido.py.
Un caligrama es un poema cuyas letras dibujan aquello de lo que habla. Apollinaire los hacía a mano. Esta librería los hace con cualquier imagen que le pases: detecta la silueta, la reduce a una rejilla de caracteres y escribe tu texto dentro, letra por letra y en orden. Lo que sale es texto plano, así que puedes pegarlo en un chat, en un README, en un commit o en una tarjeta.
$ caligrama logo.jpeg -w auto --sin-repetir -f becquer.txt
Podrá nubla
rse el sol et
ernamente; podr
á secarse en u
n instante el mar; podrá r
omperse el eje de la tierr
a como un débil crist al. ¡To
do sucede rá! Podrá la muerte
cubrir me con su fúnebre cre
spón; pero jamás en mí pod
rá ap agarse la llama de
tu amor.
Instalación
pip install caligrama
Eso es todo. No arrastra dependencias de Python (ni Pillow, ni numpy): la lectura de la imagen y el dibujo se hacen en Rust, dentro de una sola wheel que sirve para Python 3.9 en adelante en Linux, macOS y Windows. Funciona sin conexión y no manda nada a ningún lado.
En diez segundos
Desde Python:
import caligrama
print(caligrama.dibujar("gato.png", "Te quiero más que a mi café de la mañana", ancho=50))
Desde la terminal:
caligrama gato.png -w 50 -t "Te quiero más que a mi café de la mañana"
caligrama gato.png -f poema.txt # el texto desde un archivo
cat poema.txt | caligrama gato.png # o desde stdin
La imagen puede ser una ruta, un pathlib.Path o los bytes crudos (lo que te devuelve requests, una base de datos o un upload). Lee PNG, JPEG, GIF, BMP y WebP.
Diseña el texto antes de escribirlo
Lo más frustrante de hacer caligramas a mano es escribir el poema y descubrir que no cabe, o que sobra media figura. caligrama analizar te dice de antemano cuánto espacio tienes:
$ caligrama analizar logo.jpeg -w 40 -t "Podrá nublarse el sol eternamente"
Silueta a 40 columnas × 16 filas
Caben 452 letras (los espacios cuentan) ≈ 75 palabras
Tramos: 26 (de 5 a 28 letras); cada hueco entre tramos puede partir una palabra
Plantilla (letras por fila a la derecha):
############# │ 13
################# │ 17
################### │ 19
########################## ###### │ 32
########################### ####### │ 34
...
Otros anchos:
ancho filas letras ≈palabras
30 12 252 42
40 16 452 75
60 23 955 159
...
Tu texto: 33 letras. Cabe completo desde 11 columnas (-w auto). A 40 columnas sobran 419 letras.
La plantilla coincide celda por celda con el dibujo final (hay un test que lo garantiza), así que puedes contar letras por fila y ajustar tus versos a mano. Desde Python, caligrama.analizar() devuelve lo mismo en un diccionario.
Y si no quieres contar nada, ancho="auto" busca el ancho exacto en el que tu texto llena la figura una sola vez.
Por qué se ve bien con imágenes reales
Casi todas las herramientas de arte ASCII deciden qué es figura mirando el brillo: lo oscuro se pinta y lo claro se deja vacío. Eso falla más de lo que parece. En el logo de Python, la serpiente amarilla es casi tan clara como el fondo blanco y desaparece. En un pingüino, la barriga blanca queda como un agujero.
caligrama hace otra cosa:
- Estima el color del fondo con los píxeles del borde de la imagen y marca como figura lo que se aleja de ese color, con un umbral automático que se ajusta al ruido del JPEG.
- Rellena lo que está encerrado por la figura aunque sea del color del fondo. La barriga del pingüino vuelve a ser pingüino. Si quieres conservar los huecos (el ojo del logo, el centro de una dona), usa
huecos=True. - Si la imagen tiene transparencia, usa el canal alfa y listo.
suavizar=Nune trazos punteados o hechos de letras antes de muestrear, útil para logos de línea fina o imágenes que ya son arte ASCII.- Corrige la proporción de la terminal (un carácter es el doble de alto que de ancho) para que un círculo salga redondo.
- Recorre el texto por grafemas, no por bytes: tildes, ñ, ü y emojis compuestos no se parten.
Todas las opciones
| Python | Terminal | Por defecto | Qué hace |
|---|---|---|---|
ancho |
-w, --ancho |
60 |
Columnas de salida. "auto" elige el menor ancho donde cabe todo el texto. |
repetir |
--sin-repetir |
True |
Repite el texto hasta llenar la figura. |
espacios |
--espacios |
"normal" |
normal junta espacios y separa repeticiones con uno; sin los quita todos (figura más sólida); todos los deja tal cual. |
huecos |
--con-huecos |
False |
Respeta los huecos interiores del color del fondo. |
suavizar |
--suavizar |
0 |
Radio en píxeles para cerrar trazos punteados. |
invertir |
--invertir |
False |
Escribe alrededor de la figura en vez de dentro. |
umbral |
--umbral |
auto | Umbral 0–255 de separación figura/fondo, por si el automático no te convence. |
aspecto |
--aspecto |
2.0 |
Alto/ancho de un carácter en tu terminal o fuente. |
caligrama --help muestra lo mismo.
Ideas para usarlo
- Una tarjeta de cumpleaños que es su foto escrita con los mensajes de todos.
- El banner de bienvenida de tu CLI con tu logo y el nombre de la herramienta.
- Un mensaje para alguien especial, con la forma de algo que solo ustedes entienden.
- Arte generativo: como cada llamada tarda milisegundos, puedes animar. El corazón de arriba sale de un bucle de 40 llamadas cambiando el tamaño de la figura y rotando el texto.
Para verlo en acción:
python examples/demo.py # recorrido por la API
bash examples/demo.sh # recorrido por la terminal
python examples/latido.py # el corazón latiendo en tu terminal
Cómo está hecho
El núcleo (src/core.rs) es Rust puro: decodifica la imagen con el crate image, construye la máscara, la muestrea a una rejilla de caracteres y rellena. Encima hay una capa fina de PyO3 (src/lib.rs) que expone dibujar, analizar y el comando caligrama, y maturin lo empaqueta como wheel abi3. El CLI también es Rust, así que se comporta igual que la API.
Contribuir
Los issues y PRs son bienvenidos. Para montar el entorno:
git clone https://github.com/maosuarez/caligrama && cd caligrama
python -m venv .venv && source .venv/bin/activate
pip install maturin pytest
maturin develop
cargo test && pytest
Los detalles están en CONTRIBUTING.md.
Licencia
MIT. Úsalo en lo que quieras, también en proyectos comerciales.
In English
caligrama turns any image into a calligram: it finds the silhouette and writes your text inside it, in reading order, returning plain text you can paste anywhere.
pip install caligrama
caligrama cat.png -w 50 -t "your poem here"
import caligrama
print(caligrama.dibujar("cat.png", "your poem here", ancho="auto"))
info = caligrama.analizar("cat.png", "your poem here") # capacity, per-row counts, template
The core is written in Rust (PyO3 + maturin) and ships as a single abi3 wheel with zero Python dependencies. Instead of a brightness threshold it detects the background from the image border and fills enclosed regions, so light-on-white subjects keep their shape. The API and CLI flags are in Spanish; the table above maps every option.
Release files for caligrama 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| caligrama-0.1.0.tar.gz | 38.7 kB | Details |
Built distributions (wheels)
| File | Reset | |||
|---|---|---|---|---|
| caligrama-0.1.0-cp39-abi3-win_amd64.whl | CPython 3.9 | abi3 | Windows x86-64 | Details |
| caligrama-0.1.0-cp39-abi3-musllinux_1_2_x86_64.whl | CPython 3.9 | abi3 | Linux musl 1.2+ x86-64 | Details |
| caligrama-0.1.0-cp39-abi3-musllinux_1_2_aarch64.whl | CPython 3.9 | abi3 | Linux musl 1.2+ ARM64 | Details |
| caligrama-0.1.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl | CPython 3.9 | abi3 | Linux glibc 2.17+ x86-64 | Details |
| caligrama-0.1.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl | CPython 3.9 | abi3 | Linux glibc 2.17+ ARM64 | Details |
| caligrama-0.1.0-cp39-abi3-macosx_11_0_arm64.whl | CPython 3.9 | abi3 | macOS 11.0+ ARM64 | Details |
| caligrama-0.1.0-cp39-abi3-macosx_10_12_x86_64.whl | CPython 3.9 | abi3 | macOS 10.12+ x86-64 | Details |
Total release size: 5.2 MB
Release files / caligrama-0.1.0.tar.gz
| Download URL | caligrama-0.1.0.tar.gz |
|---|---|
| Size | 38.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
e2652e99151391f4a1d58b33ff115d881a720b57631751eea5be04c237c5b47d
|
|
BLAKE2b-256 checksum How to use checksums |
24211bdbf3e6bfda9d34c47578ae05685f745beb5a7f75dd5ebd1a5b362d9c97
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 24, 2026.
Transparency logRelease files / caligrama-0.1.0-cp39-abi3-win_amd64.whl
| Download URL | caligrama-0.1.0-cp39-abi3-win_amd64.whl |
|---|---|
| Size | 636.2 kB |
| Tags | CPython 3.9 Windows x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
0973c651c2056e7283d460b0084ee61b2d18e74f8640a2d5966d8791b956fc23
|
|
BLAKE2b-256 checksum How to use checksums |
3c24d1eea14638117c9e2ccf95e248fe5ada65532e94078cae647a94eb11d831
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 24, 2026.
Transparency logRelease files / caligrama-0.1.0-cp39-abi3-musllinux_1_2_x86_64.whl
| Download URL | caligrama-0.1.0-cp39-abi3-musllinux_1_2_x86_64.whl |
|---|---|
| Size | 924.0 kB |
| Tags | CPython 3.9 Linux musl 1.2+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
cc7f9bf9c3cc754f4ca3e036f2565d1add2d85a75e65f5288ea45c5ae4885da7
|
|
BLAKE2b-256 checksum How to use checksums |
4630736b6fb124df4278330c8da9f603dda0501367eb47aa8c7eb78415c4f0b3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 24, 2026.
Transparency logRelease files / caligrama-0.1.0-cp39-abi3-musllinux_1_2_aarch64.whl
| Download URL | caligrama-0.1.0-cp39-abi3-musllinux_1_2_aarch64.whl |
|---|---|
| Size | 856.0 kB |
| Tags | CPython 3.9 Linux musl 1.2+ ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
2fbb276881a4605476f7b150de891c0a274ede5542d012392647da754fd014ee
|
|
BLAKE2b-256 checksum How to use checksums |
be46d9260f6b3c6899019f0c23afae784b07663fef25648d6c6d0c5999bc2486
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 24, 2026.
Transparency logRelease files / caligrama-0.1.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | caligrama-0.1.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 710.8 kB |
| Tags | CPython 3.9 Linux glibc 2.17+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
995892f3e5d06dda7875ebb290f4d3236418acaf8653c4037d28635a4be8a4ab
|
|
BLAKE2b-256 checksum How to use checksums |
a4b506b75d3249f3c62c3be92494822356e67b60a0b5a1d4bda1e692d6128d8b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 24, 2026.
Transparency logRelease files / caligrama-0.1.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
| Download URL | caligrama-0.1.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl |
|---|---|
| Size | 677.5 kB |
| Tags | CPython 3.9 Linux glibc 2.17+ ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
7031f38475f0eda212c02f9fd95471fd33433a7e1e67a2fd245ff87d5f2b93c6
|
|
BLAKE2b-256 checksum How to use checksums |
a27a9d58944c832260d934d0aa9079b91ffb0d30d45fe30832eed03b3f13e0a5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 24, 2026.
Transparency logRelease files / caligrama-0.1.0-cp39-abi3-macosx_11_0_arm64.whl
| Download URL | caligrama-0.1.0-cp39-abi3-macosx_11_0_arm64.whl |
|---|---|
| Size | 655.3 kB |
| Tags | CPython 3.9 abi3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
523fc5656d61081967f5e8a49c179c008c041bccf2c3dac8771194b01b2c63ab
|
|
BLAKE2b-256 checksum How to use checksums |
684a58683d99701c70f8bcff02a67e029ceccbd47b05d3f629881d7ed1b3eeb2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 24, 2026.
Transparency logRelease files / caligrama-0.1.0-cp39-abi3-macosx_10_12_x86_64.whl
| Download URL | caligrama-0.1.0-cp39-abi3-macosx_10_12_x86_64.whl |
|---|---|
| Size | 682.8 kB |
| Tags | CPython 3.9 abi3 macOS 10.12+ x86-64 |
|
SHA-256 checksum How to use checksums |
8fbd3371d75e60af6160b73572911d44095d1ce51b50870640ec576a23dfdd12
|
|
BLAKE2b-256 checksum How to use checksums |
ef0c67d62ea09d2846d160c962732686f0d2c6d125270aea6f483f6dab90267d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 24, 2026.
Transparency log