Skip to content

bluevisor/terminal-cam

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

15 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

terminal-cam

Live webcam → ASCII art in your terminal. 95-char density ramp, truecolor output, painterly color styles, optional solid-block rendering, and a few fractal-driven psychedelic modes.

styles render rust license

Install

Vanilla macOS (no cargo / no Rust yet)

If you've never built a Rust project on this Mac, you need the Xcode linker and the Rust toolchain. Both installs are one command each.

# 1. Xcode Command Line Tools (needed for the linker — pops up a GUI prompt)
xcode-select --install

# 2. Rust toolchain via rustup (installs cargo into ~/.cargo/bin)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

# 3. Pick up the new PATH in this shell session
source "$HOME/.cargo/env"

After rustc --version prints something, follow the steps below.

With cargo

cargo install --git https://github.com/bluevisor/terminal-cam

The binary lands in ~/.cargo/bin/terminal-cam (already on PATH if you sourced $HOME/.cargo/env). Run it with terminal-cam.

Or clone and run from the source tree:

git clone https://github.com/bluevisor/terminal-cam
cd terminal-cam
cargo run --release

macOS will prompt for camera permission on first launch — grant it to your terminal application (System Settings → Privacy & Security → Camera).

Controls

Key Action
Esc Open / close menu
Select menu item
Change value
Enter Apply / advance
Space Save screenshot
q / Ctrl-C Quit

Options

  • Camera source — cycle detected cameras
  • StyleColor, Vivid, B&W, Grayscale, Sepia, Van Gogh, Monet, Alice, Lucy
    • Van Gogh — static palette snap. Source hue picks one of three ramps (cool / warm / green), source luma picks the anchor within it. Hand-curated from Starry Night, Irises, and the self-portrait.
    • Monet — pastelized HSV with a slow dappled-light mottle and atmospheric warm/cool shift.
    • Alice — geometry-first. Source colors pass through near-untouched; a Julia-set iteration field carves dark fractal ribbons along image edges, the source is UV-warped by a domain-warped two-octave sine field, and a slow breathing radial chromatic aberration splays RGB fringes from the corners inward.
    • Lucy — fluid-dynamic overlay. A scalar flow field built from domain-warped sine noise streams along edge tangents (perpendicular to the luma gradient) so swirls trace contours rather than crossing them; an afterimage feedback buffer leaves fading rainbow trails behind motion.
  • Render modeASCII (density-ramp glyphs) or Blocks (solid in color styles so the color escape alone carries the image; ░▒▓█ shading ramp in B&W).
  • Color depthauto / truecolor / 256 / 16. Auto-detects from COLORTERM; falls back to 256-color for terminals that don't speak 24-bit.
  • Mirror — horizontal flip (on by default; webcams are usually mirrored).
  • Brightness-1.00 to +1.00, added to each RGB channel pre-style.
  • Contrast0.1 to 3.0. Applied to RGB upstream (not just to glyph density) so it affects the emitted color, Van Gogh palette-band selection, and Alice / Lucy HSV value.
  • Screenshot path — directory used when pressing Space. Press Enter or on the row, type a path, then press Enter to save it to the app config. ~ is expanded to your home directory.

Screenshots are saved as PNG files using the current terminal crop, mirror, style, brightness, contrast, and render mode settings.

Terminal compatibility

Terminal Auto-detects as
iTerm2, Warp, Kitty, Alacritty, Ghostty, WezTerm, VS Code truecolor
Apple Terminal.app 256
anything with TERM=*-256color 256

If colors look wrong, the terminal probably doesn't support truecolor — open the menu and set Color depth to 256. The image will show some banding but the colors will be correct.

How it works

Per terminal cell, every frame:

  1. Average RGB over the source block.
  2. Add brightness offset, apply contrast stretch around mid-gray (128).
  3. Run the style transform. Palette / fractal styles produce new RGB from source luma + hue (Van Gogh), HSV rotation (Monet / Alice / Lucy), or an affine matrix (Sepia).
  4. Recompute luminance from the stylized RGB.
  5. Pick a glyph:
    • ASCII: sigmoid-shaped luma indexes the 95-char density ramp.
    • Blocks (color): solid — color escape carries brightness.
    • Blocks (B&W): ░▒▓█ shading ramp, since there's no color channel.
  6. Quantize the fg color to the selected depth (truecolor / 256-palette / ANSI-16) and emit the escape + glyph.

Each frame is wrapped in DEC 2026 synchronized-update markers (\x1b[?2026h / \x1b[?2026l) so supporting terminals paint atomically. The options overlay is composed into the same byte buffer as the render and flushed in one write — no camera-flash-behind-menu flicker.

Aspect ratio is preserved via center-crop: the source is cropped to match the terminal grid's pixel canvas (cols : rows × CHAR_ASPECT) so faces don't squash or stretch as you resize the window.

Project structure

  • src/main.rs — input loop, terminal mode setup, frame pacing
  • src/camera.rsnokhwa capture thread + shared frame slot
  • src/render.rs — per-cell render pipeline, config, synchronized output
  • src/screenshot.rs — screenshot capture + dependency-free PNG writing
  • src/config.rs — screenshot path config load/save
  • src/style.rs — style transforms (Sepia / Van Gogh / Monet / Alice / Lucy) and the Julia-set iteration helper
  • src/color.rs — depth detection + truecolor / 256 / ANSI-16 quantization
  • src/ascii.rs — 95-char density ramp and 5-stop shading ramp
  • src/menu.rs — centered options overlay (half-block title, version footer, rendered into the render buffer so it composites atomically)

Tuning

The terminal cell aspect ratio (CHAR_ASPECT = 2.0 in src/render.rs) is the one font-dependent constant. If circles render as horizontal ovals, bump it; if vertical ovals, drop it. iTerm2 / Terminal.app / Kitty with default fonts are all close to 2.0.

Van Gogh's three palette ramps live at the top of src/style.rs as VG_COOL / VG_WARM / VG_GREEN. Each is a 5-anchor ramp (dark → light); swap in your own anchors for a different painter.

Alice and Lucy's Julia c parameter drifts on a small loop — tune speed, amplitude, and center in alice() / lucy() in src/style.rs to explore different regions of the fractal parameter space.

Stack

License

MIT — see LICENSE.

About

ASCII-art webcam viewer for your terminal — Rust, 95-char density ramp, painterly color styles

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages