文生图 + 矢量叠加 (txt2img-vector-overlay)
Purpose
Generate artwork that looks like AI diffusion art but is actually precise and reproducible:
a text-to-image model paints the atmosphere (starfield, nebula, Earth limb glow, gradients),
while a code-drawn vector layer (PIL) paints the structure that diffusion cannot be trusted
with — legible text, exact element counts, accurate constellation/icon shapes, crisp labels.
The two layers are composited. This is the only reliable way to get, for example, "12 zodiac
houses each in a distinct bright color with correct Chinese names on a deep-space background at
2K resolution" — diffusion alone always garbles text, miscounts, and softens at large sizes.
When to use
- User wants AI-generated visuals and needs correct/legible text, labels, or captions.
- User needs a fixed count of repeated elements (12 houses, 7 chakras, 24 solar terms…).
- User wants accurate shapes from real data (IAU constellations, maps, schematics).
- User wants wallpaper-grade sharpness (2K/4K) from a model capped at small outputs.
- Any "make me a poster/cover/wallpaper/diagram that looks AI-generated but must be correct".
Equivalent user phrasings: "做一张…壁纸/海报,文字要清楚", "用 AI 出图但把星座/图标/文字叠上去",
"文生图背景 + 矢量贴图叠加".
Core architecture (the key insight)
Key insight — split the responsibility. Let diffusion do what it is good at (texture, lighting, mood, organic detail). Let code do what it is deterministic at (text, count, geometry, color, layout). Never ask diffusion to "draw 12 correctly-named items" — it cannot; draw them in PIL and paste.
This split is non-negotiable for the quality bar above. The failure modes of the naive
"just prompt it" approach are documented in references/pitfalls.md.
Three-phase workflow
Phase A — Generate the atmospheric background (diffusion / text-to-image)
- Pick a text-to-image model. For local/cheap high-quality atmosphere, StepFun step-2x-large
works well (seereferences/stepfun-api.md). Use the model only for the background — no
zodiac, no text, no labels in the prompt. Prompt for pure environment: deep-space starfield,
nebula gradient, Earth limb with thin blue atmospheric glow, etc. - Generate several variants (4–6) with different color moods (emerald / purple / crimson /
aurora). Keep the tidy background clean — no foreground elements, because they get covered by
the overlay anyway. - Save backgrounds as
*.pnginto your working directory'sbg/subfolder. Default working
dir is./txt2img_workunder the current shell; override with theTXT2IMG_WORKenv var.
Phase B — Prepare the vector overlay data
- Fonts: the compositor auto-detects a CJK font (Windows
simhei.ttfby default, with
fallbacks for macOS PingFang and Linux Noto/WenQuanYi) and a symbol font. Override with
FONT_CN_PATH/FONT_SYM_PATHif needed. - Real shapes (optional but recommended): the IAU constellation line data is bundled in
assets/constellations.lines.min.geojson, so no download is required at runtime. To refresh
it, runscripts/fetch_iau_lines.py(one-time). It maps a 3-letter id (Ari, Tau, …) to real
celestial line geometry. Seereferences/iau-data.mdfor the id table. - Layout config: decide arc vs grid, item box size, label offsets, per-item color. Edit the
ITEMSlist andLAYOUTconstants inscripts/compose_overlay.py.
Phase C — Composite with PIL (vector redraw, not naive upscale)
Run scripts/compose_overlay.py. It:
- Opens each background from
bg/, LANCZOS-upscales the raster to the target resolution. - Redraws the structure layer as true vectors at target resolution (constellation lines,
stars, labels) so it stays pixel-crisp — never upscales the vectors themselves. - Handles the antimeridian wrap bug (Virgo etc. stored across ±180° longitude) automatically.
- Composites vector layer over background and saves the final PNG to
out/.
C:/Users/Administrator/.workbuddy/binaries/python/envs/pillow/Scripts/python.exe \
scripts/compose_overlay.py
The script reads paths/resolution/layout from its own CONFIG block at the top; override any
path with TXT2IMG_WORK / TXT2IMG_LINES / FONT_CN_PATH / FONT_SYM_PATH. It expects a Pillow
venv (create one if missing, see references/stepfun-api.md "Pillow venv").
Hard rules
- No text in the diffusion prompt. All text/labels come from the PIL layer. Diffusion text is
always garbled. - No counting in diffusion. If the design needs N exact items, draw N items in code.
- Upscale by redrawing vectors, not by stretching. Stretching a 1280×800 render to 2K makes
everything soft; redraw lines/text at the target size. - Reduce the model's foreground load. A clean background with ~15% atmospheric glow composites
far better than a busy one; trim glow by 5–8% if foreground elements feel cramped. - Spacing: keep each item's drawn box well under the center-to-center spacing. In the zodiac
build, BOX=82 with ~105px pitch left a clear ~31px gap — tighten only after verifying.
Bundled resources
| Path | What |
|---|---|
scripts/compose_overlay.py |
Generic arc/grid compositor: bg upscale + vector overlay + antimeridian fix. Edit ITEMS/LAYOUT. |
scripts/fetch_iau_lines.py |
(Optional) Refreshes the bundled IAU constellation line geojson. |
assets/constellations.lines.min.geojson |
Real IAU constellation line data (bundled, no network needed at runtime). |
references/stepfun-api.md |
StepFun text-to-image API specifics (endpoint, key via env, image-only model, resolution cap, Pillow venv). |
references/pitfalls.md |
Every failure mode hit in the reference build and how the architecture avoids it. |
references/iau-data.md |
3-letter IAU id → name table + how coordinates are stored (antimeridian note). |
Optional: Ardot as the overlay surface
If the user is working inside the Ardot design canvas (see skills ardot-design-core /
ardot-design-router), the same split applies: use text-to-image for the canvas background
fill, then place the structure as Ardot vector nodes (text + SVG paths) instead of PIL. Prefer
PIL for batch/automated wallpaper generation; prefer Ardot when the user wants an editable design
file. Do not delegate either path to sub-agents.
Changelog
- 1.0.0 — Initial public release. Portable (env-configurable paths, cross-OS font fallback,
bundled IAU geojson). Captures the proven "background = diffusion, structure = vectors" split
with antimeridian-safe constellation rendering and vector-redraw upscaling.