Convert images to Unicode braille art for terminal display.
Features
- Encode JPEG, PNG, GIF, and BMP images as braille Unicode characters
- Animated GIF support with proper frame timing and disposal methods
- MP4 video playback with H.264 decoding
- Embedded subtitle rendering for MP4 files (mov_text format)
- Native webcam capture on macOS (AVFoundation)
- Image adjustments: gamma, brightness, contrast, sharpening
- Floyd-Steinberg dithering for grayscale preservation
- Automatic scaling to fit terminal dimensions
Installation
Homebrew (macOS/Linux)
brew install kevin-cantwell/tap/dotmatrix
Pre-built Binaries
Download from GitHub Releases. Binaries are available for:
- Linux (amd64)
- macOS (arm64, amd64)
macOS users: The binaries are not signed with an Apple Developer account. After downloading, remove the quarantine attribute:
xattr -d com.apple.quarantine dotmatrix
Install with Go
go install github.com/kevin-cantwell/dotmatrix/cmd/dotmatrix@latest
macOS users: The binary may be killed immediately due to an invalid code signature. If this happens, re-sign it:
codesign --force --sign - $(go env GOPATH)/bin/dotmatrixBuilding from Source
Building from source requires FFmpeg 8.x development libraries and CGO. Pre-built binaries have FFmpeg statically linked and require no runtime dependencies.
macOS:
brew install ffmpeg pkg-config CGO_ENABLED=1 go build -o dotmatrix ./cmd/dotmatrix
Ubuntu/Debian:
# FFmpeg 8.x may need to be built from source if not available in repos
sudo apt-get install libavcodec-dev libavformat-dev libavutil-dev libswscale-dev libswresample-dev libavdevice-dev
CGO_ENABLED=1 go build -o dotmatrix ./cmd/dotmatrixUsage
Command Line
# From file dotmatrix image.png # From URL dotmatrix https://example.com/image.jpg # From stdin curl -s https://example.com/image.jpg | dotmatrix # With options dotmatrix --invert --sharpen 50 image.png # Play MP4 video (subtitles are displayed if embedded) dotmatrix video.mp4 # Play MP4 at specific framerate dotmatrix --fps 15 video.mp4 # Capture from webcam (macOS only) dotmatrix --webcam # Webcam with options dotmatrix --webcam --invert --fps 15
As a Library
package main import ( "image" "os" "github.com/kevin-cantwell/dotmatrix" ) func main() { img, _, _ := image.Decode(os.Stdin) dotmatrix.Print(os.Stdout, img) }
Options
| Flag | Description |
|---|---|
--invert, -i |
Invert colors (for dark backgrounds) |
--gamma, -g |
Adjust gamma: negative darkens, positive lightens |
--brightness, -b |
Adjust brightness (-100 to 100) |
--contrast, -c |
Adjust contrast (-100 to 100) |
--sharpen, -s |
Sharpen image |
--mirror, -m |
Flip image horizontally |
--mono |
Disable Floyd-Steinberg dithering |
--webcam, -w |
Capture from webcam (macOS only) |
--framerate, --fps |
Set playback framerate |
--mimeType, --mime |
Override auto-detected MIME type |
Examples
Sharpened Image
dotmatrix --sharpen 100 face.jpg
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⣿⣜⢽⡺⣿⣿⣺⣿⣏⣿⣿⣿⣿⢿⣟⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣾⣿⣿⣿⣿⣿⣿⣿⣿⣽⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣜⡞⣧⢅⢳⡙⣼⣻⡢⡺⡼⣻⢞⡯⣟⣽⢻⡿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣻⣯⣿⣿⣿⡿⡿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡜⣖⢔⠕⢸⡳⡢⡱⠅⡞⣽⠱⢳⢫⡟⡞⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣱⣿⣿⣵⡿⣿⣟⡿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣽⣷⢿⡽⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
⣿⣿⣿⡿⡽⣿⢿⣻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣮⢣⢫⠀⠣⠂⢘⠐⢁⢊⠠⠉⢎⢎⢣⢿⡻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡏⡼⡜⡾⡯⡫⢽⢽⣗⢟⣿⣿⣿⣿⣿⣿⣿⣟⡮⣟⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
⣿⣿⡿⡭⡺⣫⣟⡷⣟⢾⢽⢿⣟⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣎⠄⢊⢂⠠⠈⠄⠂⠀⢁⢑⠁⢜⡧⡗⢡⢮⠿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣜⢜⢌⢊⠈⣄⢜⢿⡫⣿⣿⣿⣿⣿⣿⣿⡿⡱⣻⢟⣿⣽⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
Animated GIF
Animated GIFs play directly in the terminal with proper timing:
Note: Terminal refresh rates vary. The default macOS Terminal.app works well; iTerm2 may have slower refresh rates.
MP4 Subtitles
MP4 files with embedded subtitles (mov_text/tx3g format) will display subtitles overlaid at the bottom of the video. Subtitles are:
- Automatically extracted and timed to video playback
- Centered and wrapped to fit the terminal width
- Rendered over the braille output while preserving surrounding pixels
How It Works
Dotmatrix uses Unicode Braille Patterns (U+2800 to U+28FF) to represent images. Each braille character encodes a 2x4 pixel grid, allowing 256 possible patterns per character.
Processing pipeline:
- Decode - Parse input (JPEG, PNG, GIF, BMP, or MP4 video)
- Filter - Apply brightness, contrast, gamma, sharpening adjustments
- Scale - Resize to fit terminal dimensions (2 pixels per column, 4 pixels per row)
- Dither - Convert to monochrome using Floyd-Steinberg diffusion
- Encode - Map each 2x4 pixel block to a braille character
- Render - Output braille characters with newlines (for video, frames are rendered in sequence)
The Floyd-Steinberg dithering algorithm distributes quantization errors to neighboring pixels, preserving the appearance of grayscale gradients in the monochrome output.
License
MIT
