Skip to main content

Pippin

CI Release License Python

pippin consumes images (png, jpeg, svg) and outputs high-resolution ASCII / UTF-8 representations to your terminal. With --animate it consumes an animated gif (or video: mp4/mpeg/mov/avi/mkv/webm) and re-renders every frame as text — exporting a frame directory, a self-playing text-animation gif, or a text-animation video (mp4/mpeg).

Features

  • Input: png, jpeg, svg (plus anything Pillow opens: bmp, gif, webp, tiff)
  • Charsets: ascii, utf8, blocks (+ --custom-chars)
  • Preview to terminal (ANSI truecolor optional) and export to .txt / .ansi
  • Color coding of characters (foreground truecolor sampled from source)
  • Contrast / brightness / invert / aspect correction
  • GIF animation mode (--animate): live terminal playback, frame-directory export, and self-playing text-animation .gif re-export
  • Video animation mode (--animate with mp4/mpeg/mov/avi/mkv/webm input, requires system ffmpeg): live terminal playback, frame-directory export, and frame-for-frame text-animation video re-export (-o out.mp4 / -o out.mpeg, source audio muxed by default)

Install

No Python install required: each v* tag ships self-contained single-file binaries (.github/workflows/release.yml, matrix linux-x64|osx-arm64|win-x64) attached to that tag's GitHub Release. SVG works out of the box — cairo is bundled inside the binary.

curl -fSL -o /tmp/pippin-dl/pippin-linux-x64 https://github.com/fluxion-dev/pippin/releases/download/v0.1.0/pippin-linux-x64
chmod +x /tmp/pippin-dl/pippin-linux-x64
/tmp/pippin-dl/pippin-linux-x64 --version
# 0.1.0
gh release download v0.1.0 -p 'pippin-linux-x64' -D /tmp/pippin-dl --repo fluxion-dev/pippin
chmod +x /tmp/pippin-dl/pippin-linux-x64
/tmp/pippin-dl/pippin-linux-x64 --version
# 0.1.0

Direct asset URLs (each v* tag attaches the three binaries plus the sdist/wheel):

RID Binary Size (attached asset)
linux-x64 pippin-linux-x64 36,280,472 bytes (~34.6 MiB)
osx-arm64 pippin-osx-arm64 16,520,016 bytes (~15.8 MiB)
win-x64 pippin-win-x64.exe 23,468,705 bytes (~22.4 MiB)

Notes:

  • macOS builds are arm64 (Apple silicon) only. Downloaded binaries are unsigned — on macOS run xattr -d com.apple.quarantine pippin-osx-arm64 after downloading; Windows may show a SmartScreen prompt.
  • Prefer pip? pip install pippin-art (or pipx install pippin-art), then pippin --version. SVG via pip needs system cairo (see below).

From source (editable install with dev extras):

python3 -m venv .venv
source .venv/bin/activate
python -m pip install -e ".[dev]"

System deps for SVG (cairosvg needs cairo):

# Fedora
sudo dnf install cairo pango gdk-pixbuf2
# Debian/Ubuntu
sudo apt install libcairo2 libpango-1.0-0 libgdk-pixbuf2.0-0

Usage

# Preview (UTF-8 + color by default)
pippin photo.jpg

# ASCII, no color, fixed width
pippin logo.png --charset ascii --no-color --width 80

# Preview + export (ANSI escapes preserved when --color)
pippin input.svg --charset utf8 --color --width 120 --export out.ansi

# Export only (no terminal preview)
pippin input.jpg --export out.txt --no-preview

# Tweak rendering
pippin input.png --width 160 --contrast 1.2 --brightness 1.1 --invert
pippin input.png --charset blocks --custom-chars " .:-=+*#%@"

# Animate (uniform 12fps playback/encode by default)
pippin anim.gif --animate --width 100
pippin anim.gif --animate --width 100 --no-preview -o frames/        # frame_*.txt/.ansi + meta.json
pippin anim.gif --animate --width 100 --no-preview -o text_anim.gif  # self-playing text gif
pippin anim.gif --animate --native-timing --width 80                 # preserve source frame timing

# Animate video (requires ffmpeg on PATH; audio muxed by default)
pippin clip.mp4 --animate --width 100 --no-preview -o text.mp4      # text video, frame for frame
pippin clip.mpeg --animate --width 100 --no-preview -o text.mpeg    # mpeg -> mpeg text video
pippin clip.mp4 --animate --native-timing --width 80                # preserve source fps
pippin clip.mp4 --animate --width 100 --no-preview --no-audio -o silent.mp4

# Aspect presets: one flag picks width default + center-crop (long-form vs shorts)
pippin clip.mp4 --animate --preset landscape --no-preview -o longform.mp4   # 16:9
pippin clip.mp4 --animate --preset portrait --no-preview -o short.mp4      # 9:16 center-crop
pippin clip.mp4 --animate --preset portrait --width 80 -o short.mp4        # preset, wider grid
pippin clip.mp4 --animate --preset portrait --no-crop -o stretched.mp4     # stretch, don't crop

CLI reference

pippin INPUT [-w WIDTH] [-H HEIGHT] [--charset {ascii,utf8,blocks} | --custom-chars STR]
             [--color | --no-color] [--preview | --no-preview]
             [-o FILE] [--invert] [--contrast F] [--brightness F] [--aspect F]
             [--animate] [--fps FPS] [--native-timing] [--max-frames N] [--sample N]
             [--loop N] [--gif-font PATH] [--gif-font-size N] [--audio | --no-audio]
             [--gpu | --no-gpu]
Flag Default Meaning
INPUT — Input image path (--animate: .gif or video mp4/mpeg/mpg/mov/avi/mkv/webm)
-w, --width 100 Output width in characters (1–2000; preset default when --preset given and --width omitted)
-H, --height auto Output height in characters; auto preserves aspect with correction (explicit --height also disables preset crop)
--preset — landscape (16:9, 100 cols) or portrait (9:16, 60 cols): one-flag recipe, explicit flags still override
--quality medium Global grid-size multiplier: low 0.6x, medium 1x, high 1.6x (stills + animation)
--jobs auto Parallel frame-render workers for --animate video (0=auto by clip length, 1=serial)
--crop / --no-crop crop Center-crop to the --preset aspect / stretch to fit
--charset utf8 ascii, utf8, or blocks ramp
--custom-chars — Overrides --charset with your own dark→light ramp
--color / --no-color color ANSI truecolor foreground per character
--preview / --no-preview preview Print to stdout (still) / play animation (--animate)
-o, --export — Still: rendering file (.txt/.ansi); --animate: frame dir, .gif, or video (.mp4/.mpeg)
--invert off Invert luminance ramp
--contrast 1.0 Pillow contrast factor
--brightness 1.0 Pillow brightness factor
--aspect 0.55 Height correction for terminal cell aspect (char H ≈ 2× W). Lower = taller image.
--animate off Animation mode: render all frames as text frames (gif or video)
--fps 12 Uniform playback/encode rate (0 < fps ≤ 60); ignored with --native-timing
--native-timing off Preserve source timing (gif durations / video fps) instead of uniform --fps
--max-frames all Cap frames kept after sampling
--sample 1 Keep every Nth frame
--loop infinite preview / source loop for .gif Animation plays / GIF loop count, 0=infinite (ignored for video output)
--gif-font system monospace TTF/OTF path for --animate .gif / video rasterization
--gif-font-size 20 Font size for --animate .gif / video rasterization (8–72)
--audio / --no-audio audio Mux source audio into --animate video output / drop it
--gpu / --no-gpu gpu Use GPU video encode/decode when a working backend exists / force software

Export format: if --color is on, the export file contains ANSI escapes (.ansi-ready). With --no-color it is plain text.

Ramps

  • ascii: .:-=+*#%@ (10 levels, pure 7-bit)
  • utf8: `^\",:;Il!i~+_-?][}{1)(|\\/tfjrxnuvczXYUJCLQ0OZmwqpdbkhao*#MW&8%B@$ (70 levels)
  • blocks: ░▒▓█ (5 levels, uniform blocks)

Notes

  • SVG is rasterized via cairosvg at 3× target width, then downsampled — so vector edges stay sharp at high resolutions.
  • Transparency is composited onto black (use --invert for light terminals, compositing background is fixed black for predictable luminance).
  • For best quality use --width 120–240 with --charset utf8.
  • Video mode (--animate with video input/output) shells out to the system ffmpeg/ffprobe binaries — install ffmpeg and keep it on PATH. Conversion streams frame-by-frame (decode → convert → rasterize → encode), so RAM stays flat (~250 MB peak on a 1080p feature clip) regardless of length. Rasterization dominates CPU time, so identical frames are deduped (static scenes skip re-rendering) and convert+rasterize fans out to worker processes (--jobs, auto by clip length). The output video re-uses the text rasterizer from .gif export, so --gif-font/--gif-font-size apply to video too. Source audio is muxed by default (--no-audio drops it); .mpeg output uses mpeg2video (arbitrary fps like the 12fps default work, unlike mpeg1video).
  • GPU acceleration is best-effort and on by default (--no-gpu forces software): decode tries ffmpeg -hwaccel auto, encode prefers a probed working hardware encoder (h264_nvenc/h264_qsv/h264_amf/ h264_videotoolbox/h264_vaapi, plus mpeg2/vp9 variants) and falls back to software when none works. Probes run a real tiny encode, since capability lists don't guarantee a usable device (e.g. VMs).

Metadata

Release files for pippin-art 0.3.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pippin-art 0.3.1
File Size Uploaded
pippin_art-0.3.1.tar.gz 36.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pippin-art 0.3.1
File Interpreter ABI Platform
pippin_art-0.3.1-py3-none-any.whl Python 3 none any Details

Total release size: 67.6 kB

Release files / pippin_art-0.3.1.tar.gz

Download URL pippin_art-0.3.1.tar.gz
Size 36.1 kB
Tags Source
SHA-256 checksum
How to use checksums
70fcd1795bda1474359b2155a3cf16cb332022a808c907f95b5850957679ca71
BLAKE2b-256 checksum
How to use checksums
f439f7f628b2e2e01747ae9421dbe9f27c652fefc0630418748bfc5add2c5a45
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 Oct 14, 2026.

Transparency log

Release files / pippin_art-0.3.1-py3-none-any.whl

Download URL pippin_art-0.3.1-py3-none-any.whl
Size 31.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e1c6313a7b233bd6dd50b16e7872e1b1bb1cf28456872c1e0ea4a628a0ae5494
BLAKE2b-256 checksum
How to use checksums
fa4a487aa551f58cfb19ef53893e974e49a53004429dca3c1dd84af8e16942d0
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 Oct 14, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.3.1 This release

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page