chuda
A CPU and CUDA high-quality truecolour ANSI renderer for image-training pipelines. It implements the expensive part of Chafa's effort-9 symbol mode: exhaustive foreground/background fitting and error scoring over the narrow symbol atlas. PNG decode, high-quality resize and stateful ANSI emission stay in Rust; independent cell/symbol evaluation runs on CUDA.
RGBA images are optimized jointly for either a detailed opaque foreground and
background cell or a composable foreground-only cell. Alpha-mask agreement is
part of symbol scoring, so antialiased sprite edges do not require two renders
and a cell-level merge pass. --transparent-threshold controls the bias toward
opaque interior detail and defaults to 0.10.
The atlas is generated from the vendored Chafa reference source and checked into the Rust binary. Chafa is not a build-time or runtime dependency.
Requirements
- Rust
- CUDA Toolkit and an NVIDIA driver only when building or selecting the optional CUDA backend
Build and run
cargo build --release
cargo run --release -- --size 80 image.png > image.ansi
cargo run --release --features cuda -- --backend cuda --size 80 image.png > image.ansi
Directory mode recursively mirrors PNG paths and changes their suffix to
.ansi. It skips directory symlinks and accepts symlinks to PNG files:
cargo run --release -- --size 80 corpus --output rendered
Only ANSI is written. Directory mode does not leave resized images or other intermediates behind.
Each rendered frame is limited to 1,048,576 terminal cells. Oversized dimensions
return an error before resizing; max_batch_cells controls grouping of frames
and does not split an individual frame.
Architecture note
The public Rust and Python APIs share decoding, resizing, structured frames, and ANSI emission. Rayon and CUDA implement interchangeable cell scorers.
Python
The PyPI distribution is chuda-ansi and its import name is chuda:
import chuda
renderer = chuda.Renderer("auto")
image = chuda.Image.open("image.png")
frame = renderer.render(image, 80)
ansi = frame.to_ansi()
Updating the symbol atlas
After updating the Chafa sources in vendor/chafa, run:
python3 tools/generate_symbols.py
cargo fmt
The generated atlas is LGPL-derived and this project is correspondingly
licensed LGPL-3.0-or-later. See LICENSE and NOTICE.
Benchmark against Chafa
The benchmark excludes compilation, warms both programs once, and reports the median end-to-end batch time. It also writes one output from each renderer for visual inspection:
python3 tools/benchmark.py ../ansi-scaler/data/artifacts/rasters \
--width 80 --images 100 --repeats 3
less -R benchmark-results/sample-chuda.ansi
less -R benchmark-results/sample-chafa.ansi
Machine-readable measurements are saved in benchmark-results/report.json.
Release files for chuda-ansi 0.2.5
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| chuda_ansi-0.2.5.tar.gz | 65.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| chuda_ansi-0.2.5-cp310-abi3-manylinux_2_35_x86_64.whl | CPython 3.10 | abi3 | Linux glibc 2.35+ x86-64 | Details |
Total release size: 909.8 kB
Release files / chuda_ansi-0.2.5.tar.gz
| Download URL | chuda_ansi-0.2.5.tar.gz |
|---|---|
| Size | 65.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
89d1bdf9cc3ee1868c2eb9a35ef84a50d6f515ed6467ca4e12a46a632732f367
|
|
BLAKE2b-256 checksum How to use checksums |
f57d980b028dfcdda1163c817cd3e0268c0eb1f26035f24ec0918adfe5502ac2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / chuda_ansi-0.2.5-cp310-abi3-manylinux_2_35_x86_64.whl
| Download URL | chuda_ansi-0.2.5-cp310-abi3-manylinux_2_35_x86_64.whl |
|---|---|
| Size | 844.3 kB |
| Tags | CPython 3.10 Linux glibc 2.35+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
8759909214d7eb1a775ac60c3b14e9a673cbe8ae1845bc06be93116868e36cb2
|
|
BLAKE2b-256 checksum How to use checksums |
85839d6ce0577bfeaecc8afe8780f9dba1eafe7ebdff91d2bb6659777880c7c1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|