# Layered Img

> Turn a complex image into demo-friendly layered image assets using plan-then-execute, optional human confirmation, green sprite-sheet batching, pure-green crop extraction, transparent PNG layers, bbox/z-index metadata, and an optional editable assembly export.

- Skill: `artifact-kit/layered-img` (Agent Skill, multi-file: 4 files)
- Install (CLI): `npx skillmds@latest add artifact-kit/layered-img`
- Raw SKILL.md: https://api.skillmd.com/api/skills/artifact-kit/layered-img/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: artifact-kit (https://skillmd.com/u/artifact-kit)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/artifact-kit/layered-img

---


# Layered Image

Use this skill when the user asks for AI image layering, one-click layer splitting, image-to-layers, PSD-like layers, green-layered/sprite-sheet batching, low-token image generation, transparent PNG layer assets, or bbox/z-index layer metadata.

This is a **demo image-layering workflow**, not pixel-perfect PSD recovery. Optimize for convincing, editable layered image assets with fewer image-generation calls. DeckKit/PPT is only one assembly export path so the layers can be visually checked and dragged independently.

## Output Contract

Create one work folder:

```txt
layered-img-work/<run-name>/
  input/source.png
  prompts/
    layer-plan.json
    batch-001-prompt.txt
  generated/
    batch-001-green.png
  layers/
    batch-001-crops/
    assets/
  assembly/
    layer-compose.json
  manifests/
    run.json
    crop-manifest-batch-001.json
  scripts/
    generate_assembly_ppt.mjs
  preview/
  output/
    layered-composition.pptx
```

Required final artifacts:

- Transparent PNG layer assets under `layers/assets/`.
- `assembly/layer-compose.json` containing canvas size, layer file paths, original-image bbox, and z-index.
- `scripts/generate_assembly_ppt.mjs` using DeckKit `slide.addImage({ path, x, y, w, h })` for every layer.
- `output/layered-composition.pptx`, one optional assembly export with every layer as a separate draggable image object.

Hard boundary:

- `generated/batch-XXX-green.png` must be created by image generation.
- Do not create any `generated/batch-XXX-green.png` with scripts, source-image crops, segmentation masks, alpha masks, bbox crops, manual compositing, or OpenCV/PIL cutouts.
- Scripts may only initialize folders, crop the already-generated green sheet, build manifests, and assemble/export layers.

## Workflow

### 1. Create Work Folder

Run the bundled initializer:

```bash
python3 layered-img/scripts/init_layered_workdir.py /absolute/path/to/source.png --name <run-name>
```

Use the printed work folder for all following files. Never write generated artifacts beside the original image unless it is inside the work folder.

### 2. Plan Before Generation

Analyze the image and write `prompts/layer-plan.json` before any image generation.

Schema:

```json
{
  "source_image": "input/source.png",
  "canvas": { "width": 1024, "height": 1024 },
  "strategy": "single-batch-green-sprite",
  "green": "#00ff00",
  "batches": [
    {
      "id": "batch-001",
      "prompt_file": "prompts/batch-001-prompt.txt",
      "output_file": "generated/batch-001-green.png",
      "layers": [
        {
          "id": "main_subject",
          "label": "main subject",
          "asset_intent": "regenerate-clean-asset",
          "sprite_order": 1,
          "target_bbox": { "x": 120, "y": 80, "w": 480, "h": 760 },
          "z_index": 20,
          "include": "only the main subject",
          "exclude": "background, shadows, unrelated props"
        }
      ]
    }
  ]
}
```

Rules:

- Keep `target_bbox` in **source image pixel coordinates**.
- `sprite_order` must match left-to-right/top-to-bottom order requested in the green sprite sheet prompt.
- Use `z_index` for final assembly order; lower numbers render behind higher numbers.
- `asset_intent` should usually be `regenerate-clean-asset`: generate a clean standalone object inspired by the source, not a cropped or inpainted patch from the original image.
- For demo content, prefer 3-6 layers per batch. If too many objects exist, create multiple batches instead of one giant crowded sheet.
- Optional human confirmation belongs here: after writing the plan, show the planned layer list and ask the user to confirm only when the request allows interactive review. If the user asked for fully automatic execution, proceed with the plan.

### 3. Write The Actual Generation Prompt

For every batch, write the exact prompt to `prompts/batch-XXX-prompt.txt` before generation.

Prompt requirements:

- Ask for a pure `#00ff00` green background.
- Ask for the listed elements only, separated with clear spacing.
- Ask for no text labels, no frames, no shadows outside the object unless that layer is explicitly a shadow.
- Preserve the source image style, lighting, perspective, and object identity.
- State the exact `sprite_order`.
- Explicitly forbid source-image crop collage behavior.
- Write for img gen 2 quality, not as a terse command. Include enough visual detail for each asset: object identity, material, pose/orientation, style, lighting, camera angle, scale relationship, spacing, and cleanup constraints.
- Treat `prompts/batch-XXX-prompt.txt` as a prompt artifact and reference prompt. It is not a guarantee that the exact bytes will be passed unchanged to the image-generation backend; when calling the available image-generation tool, use this artifact as the source of truth and preserve its visual intent, layer list, order, and constraints.
- Do not include internal reasoning or chain-of-thought in the prompt artifact. Include only the generation brief that should guide image generation.

Generation mode requirements:

- Do **not** use image edit, inpainting, background removal, crop extraction, or "make this object transparent" mode for green-sheet batches.
- Do **not** ask the image model to isolate assets from the source image.
- Do **not** use Python/OpenCV/PIL/segmentation/masks to manufacture the green sheet from the source image. That is source-crop collage, not this workflow.
- Use the source image as visual reference only. If the available tool tends to paste source pixels when the image is attached, switch to a text-only generation prompt derived from the layer plan.
- Use verbs such as `redraw`, `recreate`, `regenerate`, or `illustrate as standalone assets`; avoid `extract`, `cut out`, `remove background`, `inpaint`, `keep unchanged`, or `preserve exact pixels`.
- For the opossum/character layer, ask for a complete standalone character in the same pose and style, not a partial source cutout.

Then call the available image-generation tool once per batch, using the saved prompt artifact as the reference, and save the output to `generated/batch-XXX-green.png`. Record the generation provenance in `manifests/generation-batch-XXX.json`, including the prompt file, output file, source-reference choice, and whether the generation used an attached source image or text-only prompt.

Before cropping, inspect the green-sheet output. If it has crop-collage behavior, do not continue to crop. Rewrite the prompt artifact to emphasize text-only regeneration and generate again.

Bad green-sheet outputs to reject and regenerate:

- a large copy of the original image plus some separate objects;
- cropped source patches with wall/window/floor still attached;
- an object with a green hole where another object used to be;
- a partial opossum/object cut from the source instead of a complete standalone regenerated asset;
- assets touching each other or crossing crop boundaries.

### 4. Crop Green Sprite Sheet

Use the bundled pure-green cropper script. It is vendored from the `pure-green-asset-cropper` workflow and expects a pure `#00ff00` background.

Precondition: `generated/batch-XXX-green.png` already exists and came from image generation. If the file was made by local source-image crop/mask/composite code, discard it and return to Step 3.

Cropper behavior:

- The cropper uses connected foreground regions to determine each asset's bbox, but it must not simply export every non-green pixel inside that rectangle.
- Each exported PNG must keep only the pixels belonging to that connected component; other components that fall inside the same rectangular bbox must be made transparent.
- Rectangular bboxes may overlap in `detected_boxes.jpg` and in the manifest. This is acceptable because the exported PNGs are irregular transparent layers.
- If two intended assets physically touch or are merged by `--bridge`, they are one connected component and cannot be separated by this cropper. Regenerate with more green spacing, split into another batch, lower `--bridge`, or use explicit `--exclude-box`/manual planning.

Do **not** blindly reuse fixed crop parameters. Choose parameters after inspecting the generated green sheet and the planned layer count:

- `--tolerance`: start at `3` only for a truly flat `#00ff00`; increase if compression or lighting variation makes the green non-uniform.
- `--min-area`: set based on the smallest real asset area; raise it to ignore specks, lower it to keep small items like badges or sticky notes.
- `--padding`: choose enough edge breathing room for PPT dragging, usually `8-28` px depending on asset size.
- `--bridge`: start at `0`. Increase only when one asset has separated parts that should stay together; decrease back toward `0` when neighboring objects merge.
- `--merge-distance`: use only when related pieces remain separated after bridge tuning.
- `--exclude-box`: use for unwanted generated debris, watermarks, or accidental extra objects.
- `--spill-threshold` and `--spill-softness`: tune only for green fringe/despill, not for bbox detection.

Write the chosen command into `manifests/crop-command-batch-XXX.txt` before running it.

Command shape:

```bash
python3 layered-img/scripts/crop_pure_green_assets.py \
  layered-img-work/<run-name>/generated/batch-001-green.png \
  --out-dir layered-img-work/<run-name>/layers/batch-001-crops \
  --tolerance <chosen> \
  --min-area <chosen> \
  --padding <chosen> \
  --bridge <chosen> \
  --spill-threshold <chosen> \
  --spill-softness <chosen> \
  --prefix batch_001_asset
```

Copy or save the cropper's `manifest.json` as `manifests/crop-manifest-batch-001.json`.

If objects merge or split incorrectly, tune `--bridge`, `--min-area`, `--merge-distance`, or `--exclude-box`. If edges glow green, tune only `--spill-threshold` and `--spill-softness`.

### 5. Map Crops Back To Source BBox

After crop extraction, run:

```bash
python3 layered-img/scripts/build_layer_manifest.py layered-img-work/<run-name>
```

This reads:

- `prompts/layer-plan.json`
- `manifests/crop-manifest-batch-*.json`

It writes:

- normalized layer PNGs to `layers/assets/`
- `assembly/layer-compose.json`

Open the crop preview (`layers/batch-001-crops/detected_boxes.jpg`) if order or detection looks suspicious. Fix the plan or crop parameters before building the PPT.

### 6. Generate Optional DeckKit Assembly Export

Run:

```bash
python3 layered-img/scripts/write_deckkit_script.py layered-img-work/<run-name>
```

This creates:

- `package.json`
- `scripts/generate_assembly_ppt.mjs`

Install dependencies inside the work folder:

```bash
cd layered-img-work/<run-name>
npm install
npm run generate
```

The generated script must:

- import DeckKit and DeckKit Pro;
- define a slide layout matching source image aspect ratio;
- read `assembly/layer-compose.json`;
- sort layers by `z_index`;
- convert pixel bbox to inches;
- call `slide.addImage({ path, x, y, w, h })` once per layer;
- write `output/layered-composition.pptx`.

Because every layer is added as a separate image object, the user can drag each layer independently in PowerPoint. The source of truth remains the image layer folder plus `assembly/layer-compose.json`; PPT is just the visual assembly/export format.

## DeckKit Assembly Notes

Use the DeckKit pattern from `deckkit-ppt-replica`:

```js
import DeckKit from '@artifact-kit/deckkit'
import deckkitPro from '@artifact-kit/deckkit-pro'

const pptx = new DeckKit()
pptx.use(deckkitPro())
pptx.defineLayout({ name: 'SOURCE', width: 13.333, height })
pptx.layout = 'SOURCE'
const slide = pptx.addSlide()
slide.background = { color: 'FFFFFF' }
slide.addImage({ path, x, y, w, h })
await pptx.writeFile({ fileName: outFile })
```

Do not flatten layers into one final PNG for the deliverable PPTX. A flattened preview image is allowed only as an extra QA artifact.

## Validation

Before final response:

- Confirm `assembly/layer-compose.json` parses.
- Confirm every layer file exists.
- If the assembly export is requested, confirm DeckKit script exists and uses `slide.addImage` per layer.
- Run `npm run generate` if dependencies can be installed.
- Run `unzip -t output/layered-composition.pptx` if the PPTX was generated.
- State any skipped step explicitly, especially image generation, green crop QA, npm install, or PPTX assembly generation.

