Install
openclaw skills install @zmtucker/drivethru-graphic-artistGenerate product mockups by compositing a decoration (logo/graphic) onto a blank product photo (t-shirt, hoodie, hat, mug, ...). Deterministic image manipulation only — detects the garment bounding box, scales and positions the decoration via a ratio-based placement-rules catalog, and writes a PNG. No generative AI. Use whenever the user wants to see how a logo or design looks on a garment/product, place artwork on a blank, remove an image background, or iteratively tune a print's size/position/rotation.
openclaw skills install @zmtucker/drivethru-graphic-artistTake a blank product photo plus a decoration image and return a composite mockup. Everything is deterministic image manipulation: Pillow for transform/compose, rembg (U²-Net segmentation — not generative) for background removal and garment bbox detection.
No generative AI is ever used in this pipeline. Only fall back to an image/LLM model if the user explicitly asks (e.g. "generate a new logo"), and say so before you do.
--auto-remove-bg to strip the background.full_front, left_chest, right_chest,
full_back, back_yoke, sleeve, front, …Category (hoodie / tee / hat / mug / …) is helpful but optional. If the
user doesn't say, infer it from the image or chat, or omit it to fall back to
the _defaults rules.
Placement rules are ratios against the detected garment bounding box, not
absolute pixels or inches, so a youth tee and an adult tee get visually
matching prints. Each rule has width_ratio, x_center_ratio, y_top_ratio,
and rotation_deg. Look-up order: (category, placement) →
(_defaults, placement) → error.
The catalog ships with the skill at assets/placement_rules.json (read-only
starter). When the agent adds or refines rules, an editable copy is created in
the data dir ($MOCKUP_DATA_DIR or ~/.drivethru/mockup) and persists there.
See references/placement_rules_schema.json
for the exact schema.
python3 with Pillow, rembg, and onnxruntime installed (see frontmatter
install.uv).u2net model (~170 MB) to its cache. This
needs outbound network access once; subsequent runs are offline. If the
download is blocked, bbox detection falls back to the full image frame and
--auto-remove-bg will error.| Script | Purpose |
|---|---|
scripts/compose_mockup.py | The workhorse: detect bbox, look up rule, scale/rotate/paste, write PNG, print a JSON receipt. |
scripts/detect_garment_bbox.py | Standalone: print the garment bbox JSON for a blank. |
scripts/remove_background.py | Standalone: run rembg on an image → RGBA PNG. |
scripts/edit_placement_rule.py | Schema-validated, atomic mutator for placement_rules.json (show / add / update / remove). |
python3 scripts/compose_mockup.py \
--blank /path/to/blank.jpg \
--decoration /path/to/logo.png \
--category hoodie \
--placement full_front \
[--auto-remove-bg] \
[--width-delta-pct 0] [--offset-x-pct 0] [--offset-y-pct 0] \
[--rotate-deg 0] \
[--output /path/to/out.png]
The script prints JSON with the detected garment_bbox, the resolved rule,
the applied ratios/deltas, and the output path. Return the PNG to the user
and add one line in human terms ("55% of the garment width, centered on the
chest, no rotation").
Defaults: rules come from the editable data-dir copy if present, else the
bundled starter; output goes to <data dir>/out/<uuid>.png. Override with
--rules / --output.
Mockups are a back-and-forth. When the user says "bigger", "move it up",
"rotate it", layer deltas on top of the previous run's args (e.g.
--width-delta-pct +10, --offset-y-pct -5, --rotate-deg 5). Keep a running
record of the current flags so each turn builds on the last. The full
feedback→flags mapping and how to promote a tuned result into a saved default
are in references/iterative_feedback.md.
Show the current catalog:
python3 scripts/edit_placement_rule.py show [--category hoodie] [--placement full_front]
Add a new category/placement when one is missing:
python3 scripts/edit_placement_rule.py add tote front \
--width-ratio 0.45 --x-center-ratio 0.50 --y-top-ratio 0.30
Refine an existing default (e.g. after the user approves a tuned result):
python3 scripts/edit_placement_rule.py update hoodie full_front --width-ratio 0.58
Edits are validated and written atomically to the editable copy in the data dir (seeded from the bundled starter on first edit) — the shipped asset is never mutated.
python3 scripts/remove_background.py --input /tmp/logo.jpg --output /tmp/logo.png
If the input already has meaningful transparency it is copied through unchanged
({"skipped": true}); pass --force to re-run rembg anyway.
compose_mockup.py locks it automatically; never
hand it raw pixel dimensions that would squash the decoration.