# Vermilion Sketch

> Turn a photo into a minimalist East Asian zen ink sketch: a few black brush strokes with dry-brush ends on rough embossed watercolor paper, the subject alone on empty sheet, and one small vermilion-red accent. Keeps the subject's pose and placement, strips everything else. Use whenever a user wants a photo turned into a 'zen sketch', 'ink line sketch', 'minimal ink drawing', 'brush line art', a red-accent Japanese/Chinese minimal illustration, or attaches a photo and says 'make it that simple ink style', including batches and illustrations for wallpapers, posts, slides or covers. Chinese triggers: 简笔画、禅意简笔画、水墨简笔画、极简线稿、毛笔线描、一抹红、把照片画成简笔画. Works with the host's built-in image tool (Codex, ChatGPT, Doubao, Gemini) or through any OpenAI-compatible image API that accepts several input images (gpt-image-2).

- Skill: `win-hao/vermilion-sketch` (Agent Skill, multi-file: 13 files)
- Install (CLI): `npx skillmds@latest add win-hao/vermilion-sketch`
- Raw SKILL.md: https://api.skillmd.com/api/skills/win-hao/vermilion-sketch/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Design & Media
- Author: win-hao (https://skillmd.com/u/win-hao)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/win-hao/vermilion-sketch

---


# Vermilion Sketch

Redraw a photo as a minimalist zen ink sketch: black brush-pen lines with varied weight and dry-brush ends, drawn on
cool off-white watercolor paper whose embossed tooth is clearly visible, the subject alone with generous empty paper,
and one vermilion-red motif shown as a few small stamp-like dabs. The core of the style is subtraction plus one
decision: what stays, how many strokes it gets, and where the single red goes.

Style anchors live in `assets/style-refs/` (two reference sketches that are sent to the model with every request)
and finished results in `assets/examples/`. When unsure whether a result looks right, compare against them first;
the details are in `references/style-guide.md`.

## Language

Reply in the language the user used in their first message of the conversation, and keep it for the whole session
even if later messages contain English paths, prompts or script output. Prompts sent to the image model and the
Subject Brief are always English.

## How it gets invoked

- Claude Code / Open Design: `/vermilion-sketch process this photo`, with the image dragged into the terminal (it becomes a
  path) or a path typed in. In Codex: `$vermilion-sketch ...`.
- If the user only says "process this" or "make it that style", run the full default pipeline without asking:
  aspect follows the subject, the agent picks the red and the stroke budget, one image per photo. Ask one plain-text
  multiple-choice question only when the photo has two or more equally plausible subjects.
- If the user pasted an image without a file path (common in Claude Code): look at it and write the brief first,
  then ask for the file (drag it into the terminal or give a path). The script needs a file on disk.

## Workflow

### 0. Confirm an image backend first (ten seconds; don't let the user wait until the end to discover nothing is configured)

- Host with a built-in image tool that accepts several reference images (Codex, ChatGPT, Doubao, Gemini): go to
  step 2A; no configuration needed.
- Other hosts: run `python3 "$SKILL/scripts/sketch.py" --doctor`. If it passes, continue. If it fails, no image API
  is configured yet: run `python3 "$SKILL/scripts/sketch.py" --open-env` (creates a commented `.env` from
  `.env.example` and opens it in the system editor), then tell the user in plain text, in their language, no forms:

> No image backend is configured yet. I created and opened the config file `<absolute path>/.env`; the comments explain each line:
> - You have an OpenAI-compatible image API (302.AI, OpenAI, any relay): fill section A with the key, base URL and model name.
> - You have your own image-generation command: fill the single line in section B.
> - Neither: reply "3" and I will hand you a prompt plus the two reference sketches for a web image tool.
>
> Save the file and reply "done".

When the user replies "done", run `--doctor --ping`; continue if it passes, otherwise translate the doctor output into
plain language and say which line to fix. If the user pastes the key into the chat, write it into `.env` yourself
(chmod 600) and remind them not to commit the file. "3" means the script-free path in `references/prompt-recipe.md`.
Users who prefer a terminal Q&A can run `--setup` themselves (key input is hidden). The agent's own shell has no
interactive terminal, so never try to run `--setup` on the user's behalf.

### 1. Look at the photo and write the Subject Brief

Actually look at the photo with Read; never guess from the filename. Then write the brief as a JSON file next to
the output (`<subject>.brief.json`, English values; schema and four real examples in
`references/prompt-recipe.md`). The brief holds every decision; the image model only executes it.

- **subject / silhouette / key_features**: what the user named > the largest, clearest nameable thing in the frame >
  people and animals before objects > objects before environment. Describe the pose, facing direction and the 2–4
  features that make it recognisable; the model drifts toward a generic version otherwise.
- **red_accent — you decide, never the model**: one vermilion motif, `count` pieces (1–5), each `where` spelled out,
  and `rest` naming what stays black. Choose the motif in this order: a small thing already red or warm in the photo
  (lantern, blossom, bell, collar, ribbon) > a natural small focal point (sun, moon, one fruit, one bird) > the
  smallest, most distant part of the subject (a far tower in fog) > fallback: a small low sun. If the whole subject
  is red (a red bridge, a pink lotus) draw it black and put red on its smallest part only. Count: one focal
  element = 1; a pair or small group = 2–3; scattered pieces = 3–5. `count: 0` for a pure black sketch when the
  user asks for no red.
- **stroke_plan — you decide, never the model**: list the parts worth drawing and give each an exact count and
  strokes-each (normally 1 contour). The references carry 60–80 strokes; never plan under 15 or the result is an
  icon. Ranges: a single animal 15–25, landscape 20–40, architecture 25–45; repeated units (petals, tiles, leaves,
  cables) keep the number the photo shows, up to about 30. Texture is forbidden at every budget; the budget only
  says how many things are drawn.
- **composition**: where the subject sits and how much sheet it fills; keep the photo's placement unless it fights
  the style. **aspect**: 3:4 for flowers, people, buildings, hanging branches; 4:3 for animals in profile and wide
  scenes; 1:1 otherwise; a user-specified aspect wins.
- **drop**: be blunt and complete: the town, the bridge, the reflections, the sky colour, the fur texture.

User instructions override any field ("red on the lantern", "three red spots", "no red", "simpler", "richer").

### 2. Generate: does the host have a built-in image tool?

**2A. Host with a built-in image tool** (Codex, ChatGPT, Doubao, Gemini, or an agent with an image-generation MCP):
no API needed.

- Get the exact prompt with `python3 "$SKILL/scripts/sketch.py" --image photo.jpg --brief photo.brief.json --dry-run --prompt-out prompt.txt`
  (costs nothing; if Python is unavailable, assemble it by hand from the blocks in `references/prompt-recipe.md`).
- Hand the tool the photo **first** and then the two sketches from `assets/style-refs/` as references, choose the
  aspect from the brief, paste the prompt. The paper texture comes from the references, so attach them whenever the
  tool allows. If the tool takes only one image, rerun `--dry-run` with `--no-style-ref` so the prompt carries the
  words-only paper description, and expect a flatter paper.
- If the tool has a "high fidelity to the reference" switch, leave it off unless the subject drifts.

**2B. Local script + image API** (Claude Code, Open Design and other hosts without built-in generation):

```bash
SKILL=<this skill's directory>
python3 "$SKILL/scripts/sketch.py" --image photo.jpg --brief photo.brief.json --out outputs/red-fox-sketch.png
```

- The default backend is an OpenAI-compatible image-edit endpoint (`/v1/images/edits`) with three input images:
  the photo, then the two style references. The prompt is saved next to the output as `.prompt.txt`.
- Default quality is `medium` (about ¥0.34 / $0.05 per 1536x1152 image on 302.AI, 35–60 s); it is enough for this
  style. Use `--quality low` while iterating on a brief and `high` only for a final print. Say the expected cost
  before a batch.
- If polling is interrupted, do not regenerate: the script prints a task id on submission, and
  `--resume <task_id> --image photo.jpg --out ...` fetches the finished result at no extra cost.
- Open Design's own `media generate` accepts a single input image and cannot attach the references; use any
  OpenAI-compatible key through the script instead.

### 3. Quality check

Look at the result with Read and compare it against `assets/examples/` and the anti-patterns in
`references/style-guide.md`. Repair with `--extra "..."` (appended to the prompt), one change per round, at most two
rounds:

| Symptom | Fix |
|---|---|
| Background, ground, sky or horizon came back | `--extra "Absolutely no scenery, ground plane, sky or horizon; only the listed parts on empty paper."` |
| Fur, feathers, veins, hatching or shading appeared | Name the texture: `--extra "No fur texture at all: the body is a single clean contour."` |
| Too sparse, looks like an icon (the lotus became an eight-petal symbol) | Raise `stroke_plan.total` and the repeated-unit count in the brief; add "as many petals as the photo shows" |
| Red on more spots than planned, or a red gradient | Make `where` name each spot and `rest` name the others explicitly; `--extra "Red on those spots only; every other part is black."` |
| Red sun appeared although the brief asked for something else | Keep `count` exact and add `rest: "no sun, no other red element"` |
| Paper flat and white, no tooth | The references were not attached; attach them, or run `scripts/paper_relief.py in.png out.png --strength 0.6 --bump 14` (needs Pillow) as a last resort |
| Paper looks like a stucco wall with perspective | Remove any "heavily textured / handmade paper" words from `extra`; keep "flat top-down scan" |
| Subject changed species, breed or model | Make `key_features` more specific and try `--input-fidelity high` |
| Grey wash or soft ink-painting look | `--extra "Crisp black lines only, no grey, no wash, no soft edges."` |

On hosts that cannot run the script, judge by eye against the same examples and anti-patterns.

### 4. Deliver

Tell the user, in their language: the path of the sketch (`<subject>-sketch.png`), what you chose as the subject,
where the red went and why, roughly how many strokes you budgeted, what you dropped, and which backend was used.
Process several photos one at a time and name each file after its own subject; never call everything output.png.

## Configuration (first use)

```bash
python3 "$SKILL/scripts/sketch.py" --open-env       # creates a commented .env and opens it for the user to fill in
python3 "$SKILL/scripts/sketch.py" --doctor --ping   # self-check after filling in; verifies the key online
```

Three kinds of backend, details in `references/backends.md`:
- **OpenAI-compatible image API** (302.AI, OpenAI, any relay): the default path; key, base URL and model name.
  The model must accept several input images on `/v1/images/edits`; gpt-image-2 does.
- **Your own image command or agent tool**: an `IMG_GENERATOR_CMD` template in `.env`; the script fills the
  placeholders (including `{refs}`) and runs it.
- **A web image tool**: `--dry-run --prompt-out prompt.txt` produces the prompt; the user uploads the photo and the two
  reference sketches and pastes it.

If no configuration can be found, never guess: show the user the `--doctor` output and `.env.example`.

## Don'ts

- Writing the brief without looking at the photo, or applying a "filter" to the whole photo. If the background
  stays, it is not this style.
- Leaving the red or the stroke budget to the model. It picks a red sun every time and either floods the sheet with
  red dots or collapses the subject into an icon.
- Writing ranges into the prompt ("three to five", "at most 20"). Every number is `EXACTLY N` plus what the rest does.
- Describing the paper in adjectives instead of attaching the references; "heavily textured handmade paper" turns
  into a plaster wall.
- Adding things the photo doesn't have: a second animal, calligraphy, a seal, a frame, gold, glow, gradients.
- Using `--quality high` by default.

