ctx2img
Render agent context as images. Same text, roughly 60-75% fewer tokens.
An image is billed by its pixels, not by how much text it holds. ctx2img paint
typesets any text an agent must ingest (a repo, a markdown doc, a prompt,
tool output) into dense, structured images a vision LLM reads directly,
plus a small text factsheet so exact identifiers are never trusted to
pixels.

ctx2img paint docs/DESIGN.md: this repo's entire design document (~9,800
text tokens) as one 2,550-token image: 74% cheaper, every section a
labeled box, thicker borders = more relevant to your query.
Install
curl -fsSL https://raw.githubusercontent.com/h5i-dev/h5i-ctx2img/main/install.sh | sh
Installs the latest release binary (Linux x86_64, macOS x86_64/arm64;
Windows zip on the Releases page).
Or from source: cargo install --path crates/ctx2img-cli
Usage
ctx2img paint <file|dir|-> # THE command: any text → dense image(s)
echo "$PROMPT" | ctx2img paint # paint any text via stdin — a prompt, a log, a diff
What you get depends on the input shape:
| Input | Output | Measured effect |
|---|---|---|
| markdown/doc | one section-map image + .legend.txt |
33k-char doc: 9.8k → 2.5k tokens (−74%) |
| directory | region folio: full-source tiles per module + text roster as the map | 14-file crate in one 2.6k-token tile (~2-3x vs text) |
| flat text / stdin | reflowed pages (1568×728, provider-safe) | dense code/JSON ≈ 3× fewer tokens |
directory + --budget 2000 |
navigation only: text roster, no images | whole repo mapped in 0.4s for a few hundred tokens |
Drill down when needed. Pixels are for reading, text is for exactness:
ctx2img paint src/auth -q "<task>" # focus: one module's full source as tiles
ctx2img read F103 --lines 40:120 # guaranteed-exact text for quoting/editing
ctx2img read --find "session" # search paths + symbols, answers in handles
Every render prints its counterfactual (~2550 image tok vs ~9772 text tok)
and refuses to paint when text would be cheaper. Handles (R3, F103,
§4) are stable; the factsheet carries paths/SHAs/IDs as text because VLMs
misread high-entropy strings silently.
Coding agents
cp -r skills/ctx2img ~/.claude/skills/ # Claude Code; any VLM agent can use the CLI
Prior art: pxpipe
ctx2img stands on pxpipe, which proved the premise on live Claude Code traffic: images are billed by pixels, dense 8px mono text reads at retrieval grade on frontier VLMs, high-entropy identifiers must ride as text, and imaging must be gated on profitability. ctx2img reuses those field-validated constants and aims at a different problem — not transparently compressing a request stream, but giving an agent a deliberate, structured way to ingest context:
| pxpipe | ctx2img | |
|---|---|---|
| Form | local proxy in front of Claude Code (plus pxpipe export) |
standalone CLI any agent invokes on purpose |
| Input | the request's bulky flat text (system prompt, tool docs, history) | shaped input: repo → region tiles, markdown → section map, flat text → pages |
| Layout | one dense reflowed column per page | tile packing: every section/file is a labeled box, sized by content, banded by relevance |
| Selection | image whatever the profitability gate approves | query-conditioned (-q) + token budget: most relevant first, coverage % reported, skips listed |
| Providers | Anthropic models via proxy allowlist | token-budget solvers for claude / openai / gemini / qwen; canvases shrink to fit content |
| Themes | one render profile per model | calibrated machine palettes (vlm/warm/dark) A/B-gated by ctx2img calibrate, plus the parchment human map |
| Exactness | factsheet; recent turns stay text | factsheet + stable handles (R3, F103, §4) + ctx2img read for byte-exact source |
More
--provider claude|openai|gemini|qwen: budgets solve against each provider's real image-token formula; canvases shrink to fit the content.--theme warm|dark|parchment,--layout organic: cosmetics, gated byctx2img calibrate.- Design rationale, evidence, benchmark harness: docs/DESIGN.md.
Apache-2.0 · embedded DejaVu fonts under their own license (assets/fonts/).
No comments yet
Be the first to share your take.