terminal-ascii-art is a small Rust CLI and library for rendering text, images, and video as ASCII art in the terminal.
It supports:
- Text rendering with built-in ASCII-art fonts
- PNG and JPEG image rendering
- Optional truecolor ANSI output for image and video modes
- Terminal-aware auto-sizing
- Video playback in the terminal through
ffmpeg
- Renders input text as 5-row ASCII art
- Supports
left,center, andrightalignment - Supports
plain,outline, andblockthemes
- Loads PNG and JPEG files
- Converts brightness to ASCII characters
- Can emit grayscale ASCII or ANSI-colored ASCII
- Automatically fits output to the current terminal when possible
- Uses
ffprobeto inspect source dimensions - Uses
ffmpegto decode frames into RGB24 - Streams frames to the terminal in an alternate screen buffer
- Supports looping, inversion, grayscale output, and optional hardware acceleration
- Quit playback with
q,Q, orCtrl-C
- Rust toolchain with Cargo
If ffmpeg or ffprobe are not available in PATH, video playback will fail with a clear error message.
Clone the repository and run with Cargo:
cargo run -- --helpBuild a debug binary:
cargo build
./target/debug/terminal-ascii-art --helpBuild an optimized release binary:
cargo build --release
./target/release/terminal-ascii-art --helpInstall the binary into Cargo's bin directory so it can be run as terminal-ascii-art from your shell:
cargo install --path .
terminal-ascii-art --helpIf you have not installed the binary, run commands through Cargo:
cargo run -- <COMMAND> [ARGS...]If you built locally with cargo build, use:
./target/debug/terminal-ascii-art <COMMAND> [ARGS...]If you installed the crate with cargo install --path ., use:
terminal-ascii-art <COMMAND>Available commands:
textrenders text as ASCII artimagerenders an image file as ASCII artvideoplays a video file as ASCII art in the terminal
terminal-ascii-art text [OPTIONS] <TEXT>Options:
--font <FONT>: built-in font to use, currentlystandard--align <ALIGN>:left,center, orright--width <WIDTH>: render width in columns--theme <THEME>:plain,outline, orblock
Examples:
cargo run -- text "Hello"
./target/debug/terminal-ascii-art text --theme outline "ASCII"
./target/debug/terminal-ascii-art text --align center --width 80 "Centered"
terminal-ascii-art text --theme block "LOUD"terminal-ascii-art image [OPTIONS] <PATH>Options:
--width <WIDTH>: render width in columns--invert: invert brightness-to-character mapping--color: emit 24-bit ANSI foreground color
Examples:
cargo run -- image photos/dogs.jpg
./target/debug/terminal-ascii-art image photos/one_piece_old.jpg --width 100
./target/debug/terminal-ascii-art image photos/dogs.jpg --color
terminal-ascii-art image photos/dogs.jpg --invertterminal-ascii-art video [OPTIONS] <PATH>Options:
--width <WIDTH>: render width in columns--fps <FPS>: target playback frame rate, default12--invert: invert brightness-to-character mapping--grayscale: disable ANSI color output--loop: restart playback when the video ends--hwaccel <HWACCEL>:autoornone
Examples:
cargo run -- video videos/earth_spinning.mp4
./target/debug/terminal-ascii-art video videos/earth_spinning.mp4 --width 100 --fps 15
./target/debug/terminal-ascii-art video videos/IMG_2380.MOV --grayscale --hwaccel none
terminal-ascii-art video videos/earth_spinning.mp4 --loopWhen no width is supplied, the project tries to detect the current terminal size and fit output automatically.
- Text mode uses terminal width when available
- Image and video modes fit within terminal width and height when available
- Explicit widths larger than the detected terminal width are rejected
Terminal size detection uses:
- Live terminal queries
COLUMNSandLINESenvironment variables- Fallback terminal-size detection
The crate can also be used directly from Rust code instead of invoking the CLI.
During local development, add it by path:
[dependencies]
terminal-ascii-art = { path = "../terminal-ascii-art" }If the repository is hosted remotely, depend on it by Git URL:
[dependencies]
terminal-ascii-art = { git = "https://github.com/your-name/terminal-ascii-art" }The most reusable text API is render, along with RenderOptions, Alignment, Theme, and a font implementation such as StandardFont.
use terminal_ascii_art::{Alignment, RenderOptions, StandardFont, Theme, render};
fn main() {
let options = RenderOptions {
width: Some(80),
alignment: Alignment::Center,
theme: Theme::Plain,
};
let output = render("Hello", &StandardFont, &options).unwrap();
println!("{output}");
}The crate also re-exports APIs for image and video workflows:
render_imagerender_rgb_frameplay_videoImageRenderOptionsVideoRenderOptionsHwAccelModeRenderError
If you are embedding this crate in another Rust application, these are the main entrypoints to use:
renderfor text-to-ASCII renderingrender_imagefor loading and converting PNG or JPEG filesrender_rgb_framewhen you already have decoded RGB24 frame dataplay_videowhen you want terminal playback backed byffmpeg
The crate also exposes CLI types such as Cli and Commands, plus the convenience run function. Those are mainly useful if you want to reuse or extend the command-line interface in another binary. Most library consumers will want the rendering functions listed above.
play_videorequiresffmpegandffprobeto be available inPATH- Image rendering currently supports PNG and JPEG input
- Video playback is terminal-oriented and uses an alternate screen session for drawing
See src/lib.rs for the exported API surface.
Format and test the project with:
cargo fmt --all
cargo test- src/main.rs: binary entrypoint
- src/lib.rs: library entrypoint and re-exports
- src/renderer.rs: text rendering
- src/image_renderer.rs: image and RGB frame rendering
- src/video.rs: video probing and playback
- src/terminal.rs: terminal sizing and drawing
- src/font.rs: font definitions
- src/error.rs: shared error types
The test suite covers:
- Text rendering behavior and alignment
- Image scaling and RGB frame conversion
- CLI validation and error handling
- Video argument construction and dependency handling