Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.
terminal-pixel-animation
Render pixel images as Unicode characters in the terminal with True Color support.
This library converts RGB pixel data into terminal-friendly Unicode art using two rendering backends written in high-performance systems languages (Odin and Zig), exposed to Rust via C FFI. Also available as a WebAssembly module for use in the browser.
Features
| Renderer | Language | Cells per pixel | Resolution | Best for |
|---|---|---|---|---|
| Braille | Odin | 2x4 (8 px/cell) | High | Detailed still images, thumbnails |
| Half-block | Zig | 1x2 (2 px/cell) | Medium | High frame-rate video playback |
- Aspect-ratio-preserving resize with letterboxing
- ANSI True Color (24-bit) output helpers
- Luminance-weighted color averaging with saturation boost (Braille mode)
- WebAssembly target for browser use via
wasm-pack/wasm-bindgen
Installation
Rust (crates.io)
[]
= "0.2"
npm (Browser / React)
# Core WASM module
# React hooks (optional)
Note: Requires
odin,zig, andobjcopycompilers in yourPATHat build time.
WASM (Browser)
This produces a pkg/ directory containing the WASM binary, JS glue, and TypeScript declarations. Also requires wasm-pack in your PATH.
Quick Start
Native (Terminal)
use ;
// Your RGB8 pixel buffer (width * height * 3 bytes)
let pixels: = load_your_image;
let = ;
// Render into Braille cells (80 columns x 30 rows)
let cells = render_braille.unwrap;
// Print to terminal
print_braille_to_terminal;
WASM (Browser)
import init from "terminal-pixel-animation";
await ;
// Your RGB8 pixel buffer as a Uint8Array
const cells = ;
// Decode Braille cells
React
import { WasmProvider, useBraille } from "terminal-pixel-animation-react";
function App() {
return (
<WasmProvider>
<PixelCanvas />
</WasmProvider>
);
}
function PixelCanvas() {
const [pixels, setPixels] = useState<Uint8Array | null>(null);
const { decoded, loading } = useBraille(pixels, 320, 240, 80, 30);
if (loading) return <p>Loading WASM...</p>;
if (!decoded) return null;
return (
<pre style={{ fontFamily: "monospace", lineHeight: "1", fontSize: "10px" }}>
{decoded.map((cell, i) => (
<span key={i} style={{ color: `rgb(${cell.r},${cell.g},${cell.b})` }}>
{cell.char}
</span>
))}
</pre>
);
}
API
Rendering (Native)
// Braille: 8 bytes per cell [utf8;4, R, G, B, _]
let cells = render_braille?;
// Half-block: 6 bytes per cell [R_fg, G_fg, B_fg, R_bg, G_bg, B_bg]
let cells = render_half_block?;
Rendering (WASM)
// Braille: Uint8Array, 8 bytes per cell [utf8_byte0, utf8_byte1, utf8_byte2, utf8_byte3, R, G, B, _]
const cells = ;
// Half-block: Uint8Array, 6 bytes per cell [R_fg, G_fg, B_fg, R_bg, G_bg, B_bg]
const cells = ;
Terminal Output
print_braille_to_terminal;
print_halfblock_to_terminal;
Custom Rendering
The library returns raw cell buffers, so you can implement your own output:
let cells = render_braille?;
for row in 0..24
React Hooks
import { WasmProvider, useBraille, useHalfBlock } from "terminal-pixel-animation-react";
// Wrap your app with WasmProvider (loads the WASM module once)
function App() {
return (
<WasmProvider>
<MyComponent />
</WasmProvider>
);
}
function MyComponent() {
// Pass RGB8 pixel data; hook returns decoded cells
const { cells, decoded, loading, error } = useBraille(pixels, 320, 240, 80, 30);
// decoded: [{ char, r, g, b }, ...] — flat array, row-major order
const halfblock = useHalfBlock(pixels, 320, 240, 80, 30);
// halfblock.decoded: [{ rFg, gFg, bFg, rBg, gBg, bBg }, ...]
}
Building from Source
Native
WASM
The build script detects the target architecture and cross-compiles Odin and Zig source files accordingly (freestanding_wasm32 / wasm32-freestanding for WASM).
Dependencies
- Rust (edition 2024)
- Odin compiler
- Zig compiler
objcopy(binutils)- wasm-pack (for WASM builds)
Example
Native
WASM
After building with wasm-pack, serve the pkg/ directory and open the demo:
# Open http://localhost:8080/pkg/wasm-demo.html in your browser
The demo supports webcam live feed and video file playback, rendering frames to a canvas using requestAnimationFrame.
React
&& &&
Publishing
npm (WASM core + React hooks)
# 1. Login to npm (first time only)
# 2. Publish the core WASM package
# 3. Publish the React hooks package
crates.io (Rust crate)
# 1. Login to crates.io (first time only)
# 2. Publish
Version Management
# Update versions before publishing
License
MIT