Thanks to visit codestin.com
Credit goes to lib.rs

#ascii-art #image-converter #art #image #ascii-image

bin+lib cascii

High-performance ASCII art generator for images and videos

2 unstable releases

new 0.3.0 Jan 14, 2026
0.2.0 Dec 28, 2025

#517 in Images

Codestin Search App Codestin Search App Codestin Search App

54 downloads per month

MIT/Apache

64KB
1K SLoC

Codestin Search App Codestin Search App

cascii - Interactive ASCII Frame Generator

cascii is a high-performance, interactive tool for converting videos and image sequences into ASCII art frames.

New: cascii can now be used as both a CLI tool and a Rust library!

When converting a video, the output files will be placed in a directory named after the video file. For example, cascii my_video.mp4 will create a my_video directory.

I recommend installing cascii-viewer to easily play any ascii animation generated

Features

  • Interactive Mode: If you don't provide arguments, cascii will prompt you for them.
  • Flexible Input: Works with video files or directories of PNGs.
  • Performance: Uses ffmpeg for fast frame extraction and parallel processing with Rayon for ASCII conversion.
  • Video Segments: Specify start and end times to convert only a portion of a video.
  • Presets: --small and --large flags for quick quality adjustments.
  • Non-interactive Mode: Use --default to run without prompts, using default values.
  • Library Support: Use cascii as a dependency in your own Rust projects.

Installation

As a CLI Tool

An install.sh script is provided to build and install cascii to /usr/local/bin.

# Make sure you are in the cascii directory
./install.sh

You will be prompted for your password as it uses sudo to copy the binary.

Alternatively, install from crates.io (once published):

cargo install cascii

As a Library

Add to your Cargo.toml:

[dependencies]
cascii = "0.1"

CLI Usage

CLI Usage

cascii

Interactive

Run cascii without any arguments to be guided through the process:

cascii

It will first ask you to select an input file from the current directory, then prompt for the output directory, and finally for the quality settings.

With Arguments

You can also provide arguments directly:

# Basic usage with a video file
cascii my_video.mp4 --out ./my_frames

# Using presets
cascii my_video.mp4 --out ./my_frames --large

# Non-interactive mode (will fail if input is not provided)
cascii my_video.mp4 --out ./my_frames --default

# Convert a 5-second clip starting at 10 seconds into the video
cascii my_video.mp4 --start 00:00:10 --end 00:00:15

Options

  • [input]: (Optional) The input video file or directory of images.
  • -o, --out: (Optional) The output directory. Defaults to the current directory.
  • --columns: (Optional) The width of the output ASCII art.
  • --fps: (Optional) The frames per second to extract from a video.
  • --font-ratio: (Optional) The aspect ratio of the font used for rendering.
  • --start: (Optional) The start time for video conversion (e.g., 00:01:23.456 or 83.456).
  • --end: (Optional) The end time for video conversion.
  • --default: Skips all prompts and uses default values for any missing arguments.
  • -s, --small: Uses smaller default values for quality settings.
  • -l, --large: Uses larger default values for quality settings.
  • -h, --help: Shows the help message.
  • -V, --version: Shows the version information.

Examples:

Source image:

Source image

Test 1:

settings:

Luminance: 1
Font Ratio: 0.7
Columns: 400

Test 1 output

Test 2:

settings:

Luminance: 35
Font Ratio: 0.7
Columns: 400

Test 2 output

Test 3:

settings:

Luminance: 35
Font Ratio: 0.5
Columns: 400

Test 3 output

Test 4:

settings:

Luminance: 35
Font Ratio: 1
Columns: 400

Test 4 output

Test animation 1:

Reconstituting a few seconds from the clip Aleph 2 by Max Cooper (around 2:30 to 3:00)

Frames: 960
Luminance: 30
Font Ratio: 0.7
Columns: 400
FPS: 30

Demo

Library Usage

cascii can be used as a Rust library in your own projects.

Basic Example - Convert an Image to ASCII

use cascii::{AsciiConverter, ConversionOptions};
use std::path::Path;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Create a converter with default configuration
    let converter = AsciiConverter::new();

    // Configure conversion options
    let options = ConversionOptions::default()
        .with_columns(200)
        .with_font_ratio(0.7)
        .with_luminance(20);

    // Convert image to ASCII file
    converter.convert_image(
        Path::new("input.png"),
        Path::new("output.txt"),
        &options
    )?;

    Ok(())
}

Convert Image to String (No File)

use cascii::{AsciiConverter, ConversionOptions};
use std::path::Path;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let converter = AsciiConverter::new();
    let options = ConversionOptions::default().with_columns(100);
    
    // Get ASCII as a string without writing to file
    let ascii_string = converter.image_to_string(
        Path::new("input.png"),
        &options
    )?;
    
    println!("{}", ascii_string);
    Ok(())
}

Convert a Video to ASCII Frames

use cascii::{AsciiConverter, VideoOptions, ConversionOptions};
use std::path::Path;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let converter = AsciiConverter::new();

    // Video extraction options
    let video_opts = VideoOptions {
        fps: 30,
        start: Some("0".to_string()),
        end: Some("10".to_string()),  // First 10 seconds
        columns: 400,
    };

    // ASCII conversion options
    let conv_opts = ConversionOptions::default()
        .with_font_ratio(0.7)
        .with_luminance(20);

    // Convert video
    converter.convert_video(
        Path::new("video.mp4"),
        Path::new("output_frames/"),
        &video_opts,
        &conv_opts,
        false  // Don't keep intermediate PNG files
    )?;

    Ok(())
}

Using Presets

use cascii::AsciiConverter;
use std::path::Path;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let converter = AsciiConverter::new();

    // Use built-in presets: "default", "small", or "large"
    let small_options = converter.options_from_preset("small")?;
    
    converter.convert_image(
        Path::new("input.png"),
        Path::new("output.txt"),
        &small_options
    )?;

    Ok(())
}

API Reference

AsciiConverter

Main converter struct for ASCII art generation.

Methods:

  • new() - Create converter with default configuration
  • with_config(config: AppConfig) - Create with custom configuration
  • from_config_file(path: &Path) - Load configuration from file
  • convert_image(input, output, options) - Convert image to ASCII file
  • image_to_string(input, options) - Convert image to ASCII string
  • convert_video(input, output_dir, video_opts, conv_opts, keep_images) - Convert video to ASCII frames
  • convert_directory(input_dir, output_dir, options, keep_images) - Convert directory of images
  • get_preset(name) - Get a preset by name
  • options_from_preset(name) - Get conversion options from a preset

ConversionOptions

Options for ASCII conversion.

Fields:

  • columns: Option<u32> - Target width in characters
  • font_ratio: f32 - Font aspect ratio (width/height)
  • luminance: u8 - Luminance threshold (0-255)
  • ascii_chars: String - ASCII character set (darkest to lightest)

Methods:

  • default() - Create with default options
  • with_columns(columns) - Set target width
  • with_font_ratio(ratio) - Set font ratio
  • with_luminance(threshold) - Set luminance threshold
  • with_ascii_chars(chars) - Set custom character set

VideoOptions

Options for video conversion.

Fields:

  • fps: u32 - Frames per second to extract
  • start: Option<String> - Start time (e.g., "00:01:23" or "83")
  • end: Option<String> - End time
  • columns: u32 - Target width in characters

Examples

See the examples/ directory for complete examples:

  • simple_image.rs - Basic image conversion
  • simple_video.rs - Video conversion

Run examples with:

cargo run --example simple_image
cargo run --example simple_video

Sample commands

Test Image

./target/release/ascii-gen
--input ./some_frames_dir
--out ../output/sunset_hl
--font-ratio 0.7

Test Video

./target/release/ascii-gen
--input ../input.webm
--out ../output/sunset_hl
--columns 800
--fps 30
--font-ratio 0.7

Acknowledgements

This project is inspired by developedbyed's video that I recommend watching, I reused the logic from his bash script and rewrote it in rust so that it could process faster files with more details.

Dependencies

~14–25MB
~345K SLoC