ASCII Art & Terminal Renderer
A small command-line application for rendering images, videos, and procedural 3D experiments directly in a terminal.
The project treats the terminal as a character-based framebuffer. Pixel brightness selects an ASCII character, ANSI escape sequences provide true color and screen updates, and mathematical renderers supply geometry, projection, lighting, and depth.
source pixels or 3D geometry
↓
brightness / lighting
↓
character mapping
↓
optional ANSI color
↓
terminal
Features
- One
ascii-artcommand for every renderer. - Still-image conversion with automatic aspect-ratio correction.
- Monochrome and ANSI true-color video playback.
- Optional synchronized audio through FFplay.
- Frame dropping to limit long-term audio/video drift.
- Configurable FPS, width, character ramp, color smoothing, and inversion.
- Automatic fitting to the current terminal.
- Five procedural demos: cube, sphere, donut, planet, and black hole.
- Safe terminal cleanup after completion, errors, or
Ctrl+C. - Compatibility entry points for the original scripts.
Requirements
- Python 3.10 or newer.
- Pillow for still images.
- NumPy for video frame processing.
- FFmpeg for video decoding.
- FFplay for audio playback, unless
--no-audiois used. - FFprobe is recommended for detecting the source video's dimensions. A 16:9 fallback is used when it is unavailable.
Check the external video tools:
ffmpeg -version
ffplay -version
ffprobe -version
On Windows, install an FFmpeg distribution containing all three programs and ensure its executable directory is on PATH.
Installation
Install the published package from PyPI:
python -m pip install --upgrade pip
python -m pip install terminal-ascii-art
Confirm that the command is available:
ascii-art --version
ascii-art list
If ascii-art is not found because your Python scripts directory is not on PATH, use the module form:
python -m terminal_ascii_art list
Python installations normally include pip. If python -m pip --version reports that pip is missing, bootstrap it with:
python -m ensurepip --upgrade
Install from source
Clone the repository and enter it:
git clone https://github.com/TFQ0/ASCII-Art.git
cd ASCII-Art
Create and activate a virtual environment:
py -m venv .venv
.venv\Scripts\Activate.ps1
Install the project in editable mode:
python -m pip install -e .
The editable installation provides the ascii-art command. The same interface can also be invoked as a Python module:
python -m terminal_ascii_art list
Quick start
Replace the example paths below with paths to your own image and video files.
List every available renderer:
ascii-art list
Convert an image:
ascii-art image "C:\path\to\photo.jpg" --width 100
Play a monochrome video with audio:
ascii-art video "C:\path\to\video.mp4"
Play a true-color video:
ascii-art video "C:\path\to\video.mp4" --color --fps 20 --width 120
Run a procedural demo:
ascii-art demo cube
Press Ctrl+C to stop an animation or video.
Input files do not need to be inside the repository. Quote paths that contain spaces. For example, in PowerShell:
ascii-art video "E:\Videos\Rena Circulation.mp4" --color --charset detailed --fps 20 --width 120
The equivalent Git Bash path is:
ascii-art video "/e/Videos/Rena Circulation.mp4" --color --charset detailed --fps 20 --width 120
Image rendering
ascii-art image IMAGE [options]
Examples:
# Print the result in the terminal
ascii-art image photo.png --width 120
# Write plain ASCII to a UTF-8 text file
ascii-art image photo.png --width 120 --output output\photo.txt
# Use a longer character ramp and reverse its brightness direction
ascii-art image photo.png --charset detailed --invert
Options:
| Option | Purpose |
|---|---|
--width N |
Maximum output width. Default: 100. |
--height N |
Optional maximum output height. |
--charset NAME |
classic, detailed, or letters. |
--invert |
Reverse the dark-to-bright ramp. |
-o, --output PATH |
Write the rendered text to a file. |
The source ratio is preserved while accounting for terminal cells being approximately twice as tall as they are wide.
Video rendering
ascii-art video VIDEO [options]
The default mode is monochrome with audio enabled. Add --color to preserve approximate source colors using ANSI 24-bit foreground codes.
Examples:
# Monochrome video without audio
ascii-art video clip.mp4 --no-audio
# Detailed true-color playback
ascii-art video clip.mp4 --color --charset detailed --width 160 --fps 20
# Add motion trails
ascii-art video clip.mp4 --color --smoothing 0.35
# Delay audio by 0.5 seconds
ascii-art video clip.mp4 --audio-delay 0.5
Options:
| Option | Purpose |
|---|---|
--color |
Enable ANSI true-color output. |
--fps N |
Target playback rate. Default: 20. |
--width N |
Maximum render width. Default: 160. |
--smoothing N |
Temporal blend from 0 to 1; 1 is crisp. |
--quant N |
Color quantization step used to reduce ANSI output. Default: 4. |
--max-frame-skip N |
Consecutive frames that may be dropped to catch up. Default: 5. |
--no-audio |
Do not start FFplay. |
--audio-delay N |
Shift audio by -30 to +30 seconds; positive values delay it. |
--charset NAME |
classic, detailed, or letters. |
--invert |
Reverse the selected brightness ramp. |
The video pipeline is:
┌─ FFmpeg → scaled raw frames → NumPy → ASCII → terminal
source video ──────────┤
└─ FFplay → audio
The renderer uses a wall-clock schedule. When terminal rendering falls behind, it can discard a bounded number of decoded frames instead of allowing drift to grow continuously.
Procedural demos
ascii-art demo NAME [options]
Available names:
| Demo | Technique |
|---|---|
cube |
Vertex rotation, perspective projection, face normals, back-face culling, triangle filling, and interpolated depth buffering. |
sphere |
Per-cell sphere reconstruction and directional lighting. |
donut |
Parametric torus sampling, normal-based lighting, perspective, and depth buffering. |
planet |
Rotating sphere with procedural terrain, a night side, and an atmospheric rim. |
blackhole |
Polar-coordinate accretion disk, deterministic stars, asymmetric glow, and a photon-ring effect. |
Examples:
ascii-art demo donut --fps 30
ascii-art demo planet --width 120 --charset detailed
ascii-art demo blackhole --width 140 --height 50
Every demo accepts --width, --height, --fps, --charset, and --invert. Dimensions are reduced when necessary to fit the terminal.
Character ramps
Character ramps are ordered from dark to bright:
classic: " .:-=+*#%@"
detailed: a longer ramp with finer brightness changes
letters: a dense, text-like ramp
To add a procedural demo:
- Create a module under
terminal_ascii_art/renderers/. - Implement
render_frame(frame_index, width, height, ramp) -> str. - Register it in
terminal_ascii_art/renderers/__init__.py. - Add a renderer-contract or algorithm-specific test.
- Document the new demo here.
Testing
Install the project and run the test suite from the repository root:
python -m pip install -e .
python -m unittest discover -s tests -v
Publishing a release
Releases are published from TFQ0/ASCII-Art by .github/workflows/publish.yml. The workflow runs the tests on the supported Python versions, builds and validates the wheel and source distribution, and publishes them to PyPI through Trusted Publishing.
Before the first release, configure a PyPI Trusted Publisher for the terminal-ascii-art project with these exact values:
- Owner:
TFQ0 - Repository:
ASCII-Art - Workflow:
publish.yml - Environment:
pypi
The GitHub pypi environment permits tags matching v*. If the account that creates the release is its only required reviewer, Prevent self-review must be disabled or another reviewer must be added.
For every release:
-
Update
__version__interminal_ascii_art/__init__.py. Package metadata reads the version from this single source. -
Run the tests.
-
Build and validate the distributions locally:
python -m pip install --upgrade build twine python -m build python -m twine check dist/*
-
Commit and push the release changes.
-
Create a GitHub release whose tag exactly matches the package version with a
vprefix, such asv0.1.1.
Publishing a GitHub release triggers the workflow. PyPI does not allow an existing release file or version to be overwritten, so each published version must be unique.
Performance and limitations
Terminal output is much slower than GPU rendering. Performance depends on the CPU, terminal emulator, selected width, FPS, character ramp, and whether ANSI color is enabled.
Useful starting points:
80columns for low overhead.120columns for balanced detail.160columns for high detail on a capable terminal.- Monochrome mode when color output is too expensive.
- A larger
--quantvalue to reduce ANSI color changes.
License
This project is distributed under the MIT License.
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 terminal_ascii_art-0.1.1.tar.gz.
File metadata
- Download URL: terminal_ascii_art-0.1.1.tar.gz
- Upload date:
- Size: 23.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3dc2be114e4eeb04037110e175a72faaad79470097464026d29b02403478e9aa
|
|
| MD5 |
a16373b962894ef1220dae2cb34ea585
|
|
| BLAKE2b-256 |
ede1e3a5619c1adc510b48fee449495c2f6d62c837985f58e850ae9309aa2a90
|
Provenance
The following attestation bundles were made for terminal_ascii_art-0.1.1.tar.gz:
Publisher:
publish.yml on TFQ0/ASCII-Art
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
terminal_ascii_art-0.1.1.tar.gz -
Subject digest:
3dc2be114e4eeb04037110e175a72faaad79470097464026d29b02403478e9aa - Sigstore transparency entry: 2698572201
- Sigstore integration time:
-
Permalink:
TFQ0/ASCII-Art@969afb5123df3e583e8462f82f3c052d07594065 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/TFQ0
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@969afb5123df3e583e8462f82f3c052d07594065 -
Trigger Event:
release
-
Statement type:
File details
Details for the file terminal_ascii_art-0.1.1-py3-none-any.whl.
File metadata
- Download URL: terminal_ascii_art-0.1.1-py3-none-any.whl
- Upload date:
- Size: 21.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bfbe8adf3a90f5ebcc3c4ac4c9010c6cffec616d74dc1ec4fb775eefb87631aa
|
|
| MD5 |
fd3e123dac3870bd83fffc1398bde9bf
|
|
| BLAKE2b-256 |
b6a7255990724aabec6c444eea94d2dcea3881439b955b7a5de6d4c594961b8e
|
Provenance
The following attestation bundles were made for terminal_ascii_art-0.1.1-py3-none-any.whl:
Publisher:
publish.yml on TFQ0/ASCII-Art
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
terminal_ascii_art-0.1.1-py3-none-any.whl -
Subject digest:
bfbe8adf3a90f5ebcc3c4ac4c9010c6cffec616d74dc1ec4fb775eefb87631aa - Sigstore transparency entry: 2698572282
- Sigstore integration time:
-
Permalink:
TFQ0/ASCII-Art@969afb5123df3e583e8462f82f3c052d07594065 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/TFQ0
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@969afb5123df3e583e8462f82f3c052d07594065 -
Trigger Event:
release
-
Statement type: