API Reference

termimage.Display

func Display(w io.Writer, src string, opts Options) error

Decodes the image at src and writes terminal graphics to w. src may be:

  • a local file path (/path/to/cat.png)
  • an http(s):// URL
  • a data: URI with a base64 payload (data:image/png;base64,...)

Remote URLs and data URIs are fetched/decoded in the parent process, then piped to the sandboxed worker over stdin. Payloads are capped at 64 MiB.

Returns the first error encountered (fetch, decode, or render failure).

termimage.DisplayContext

func DisplayContext(ctx context.Context, w io.Writer, src string, opts Options) error

Same as Display with a context.Context for cancellation of HTTP fetches and sandboxed decoding.

termimage.DisplayWithSize

func DisplayWithSize(w io.Writer, src string, opts Options) (cols, rows int, err error)
func DisplayContextWithSize(ctx context.Context, w io.Writer, src string, opts Options) (cols, rows int, err error)

Same as Display but also returns the terminal character-cell dimensions the rendered image occupies. Use this instead of Display + a separate size calculation to avoid decoding the image twice.

Protocolcolsrows
HalfBlockimage pixel widthceil(image pixel height / 2)
Kitty / Sixelceil(pixel width / cell width)ceil(pixel height / cell height)

Cell pixel dimensions are read from the terminal via TIOCGWINSZ; fallback is 8×16 px/cell.

termimage.Clear

func Clear(w io.Writer, proto Protocol, rows int) error

Erases a previously rendered image.

ProtocolBehaviour
KittySends \x1b_Ga=d,d=A\x1b\\ (delete all visible placements). rows is ignored.
Sixel, HalfBlockMoves cursor up rows lines then erases to end of screen (\x1b[{rows}A\x1b[J). Cursor must be on the last row of the image before calling.

Pass the rows value returned by DisplayWithSize.

termimage.Options

type Options struct {
    MaxWidth, MaxHeight int
    Protocol            Protocol
    Sandboxed           bool
}
FieldDefaultDescription
MaxWidthterminal cols (character cells)Max pixel width. For HalfBlock: 1 px = 1 character column.
MaxHeight(terminal rows − 2) × 2 for HalfBlock; (terminal rows − 2) × cell height px for Kitty/SixelMax pixel height. Minus 2 rows leaves headroom for the shell prompt.
ProtocolAutoAuto, Kitty, Sixel, HalfBlock
SandboxedfalseRun decode in isolated subprocess

Aspect ratio: MaxWidth and MaxHeight are independent upper bounds. resize.Fit computes scale = min(MaxWidth/srcW, MaxHeight/srcH) and applies it uniformly — the image fills whichever dimension is the tighter constraint. When only one dimension is set explicitly, the other comes from terminal detection.

HalfBlock and text layout: HalfBlock renders using real terminal character cells ( U+2580). Unlike Kitty or Sixel, the output occupies rows × cols cells in the scroll buffer. Cursor save/restore (\x1b[s / \x1b[u) does not undo cell content. TUIs that need pixel-layer rendering should use Kitty or Sixel: call detect.Best() first and handle the case where it returns HalfBlock.

termimage.MaybeRunWorker

func MaybeRunWorker()

Must be called at the top of main() when using Sandboxed: true. Checks for the TERMIMAGE_WORKER=1 env var; if set, applies OS restrictions, decodes the image, writes raw RGBA to stdout, and calls os.Exit(0).

Sub-packages

PackagePurpose
decodeCGo stb_image binding. decode.File(path) and decode.Bytes(data)
detectProtocol detection. detect.Best()
renderrender.Kitty, render.Sixel, render.HalfBlock
sandboxSubprocess worker. sandbox.Decode(path), sandbox.DecodeBytes(data)
internal/sourceSource resolver. Branches file path / data: URI / http(s):// URL
internal/resizeresize.Fit(img, maxW, maxH) — aspect-preserving BiLinear scale