Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions skills-manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@
"files": 12
},
"media-use": {
"hash": "1b0ce647f5c7df95",
"files": 152
"hash": "15f2c5759218773a",
"files": 157
},
"motion-graphics": {
"hash": "69dc088b8e0d22fe",
Expand Down
1 change: 1 addition & 0 deletions skills/media-use/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ Rules that keep this a help, not nagware: **grounded, not generic** (no signal
| color grading, LUTs, smart grade (`--for`), grade-compare | `references/grading.md` |
| voiceover / TTS, music, SFX, captions, transcription (audio engine) | `references/audio.md` |
| cut / reframe / transform existing media, exact error diffusion, HEVC | `references/operations.md` |
| paint an image (or video frame) as brushstroke code (image-to-code) | `references/paint.md` |
| source-aware creative treatments, realtime effects, overlays, reveals | `references/media-treatments.md` |
| install + auth, provider table, RAM ladders, `--local-only`, `--provider` | `references/setup-providers.md` |
| remembered preferences + frozen recipes (user memory) | `references/memory.md` |
Expand Down
69 changes: 69 additions & 0 deletions skills/media-use/references/paint.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# Paint — image-to-code compositions

`paint` compiles an image (or one frame of a video) into a standalone
HyperFrames composition whose **generated code repaints the subject in
brushstrokes**. The artifact is the code: the stroke list ships as an editable
data module (`strokes.js`), and the runtime reveals it over the timeline.
Deterministic: same input + seed produces byte-identical output.

## When to reach for it

- A composition needs a painted, hand-marked look derived from a real image
(a portrait, a logo, a product shot, a frame of footage).
- The brief says "paint this", "make it look brush-painted", or asks for the
image to draw itself on screen.
- You want the image-to-code thesis artifact: code the user can edit.

## Run it

```bash
node <SKILL_DIR>/scripts/paint.mjs --input photo.jpg --out paint-photo [options]
```

| Option | Default | Meaning |
| ---------------------- | -------------- | ----------------------------------------- |
| `--input <path>` | required | source image or video (one frame sampled) |
| `--out <dir>` | `paint-<name>` | output folder |
| `--seed <n>` | `1337` | stroke randomness seed |
| `--width <px>` | `1100` | emitted canvas width |
| `--duration <s>` | `12` | reveal duration in seconds |
| `--detail <level>` | `medium` | `low` / `medium` / `high` stroke budget |
| `--video-position <s>` | `0` | frame sample time for video inputs |
| `--json` | off | machine-readable summary |

Requires `ffmpeg`/`ffprobe` on PATH (the same decode path as the rest of
media-use's operations).

## Output

```
paint-photo/
index.html standalone composition (contract-correct root, clip, timeline)
strokes.js editable stroke data — window.__PAINT_STROKES = [...]
```

The painter runtime is inlined in `index.html`. It reveals strokes in array
order over `--duration` seconds and is **seek-safe by construction**: band
canvases are pure functions of their index, so any seek order lands on
identical pixels. `hyperframes check` passes on the emitted folder as-is.

## Using the output

- **As its own composition**: point `check` / `preview` / `render` at the
folder, or copy it into a project's `compositions/` and mount it.
- **Inside an existing composition**: mount via
`data-composition-src` (wrap the emitted root in `<template>` per the
sub-composition contract), or paste the inline runtime + a `<canvas>` into
your scene and load `strokes.js` alongside it.
- **Editing the art**: `strokes.js` is plain data. Reorder strokes to change
the reveal, delete strokes to simplify, tweak `color`/`weight`/`angle` per
stroke. The runtime never needs to change.

## Tuning

- `--detail high` resolves faces and fine texture (~60k strokes on a busy
image); `medium` is the balanced default; `low` suits backgrounds.
- Same seed, same image → identical strokes. Change `--seed` for a different
interpretation of the same subject.
- The reveal order IS the compile order (coarse underpainting first, fine
detail last). Reversing the array reverses the reveal.
Loading
Loading