Skip to main content

layerize

Use when rebuilding a flat raster image — an ad, banner, social post, poster or other creative (PNG / JPEG / WebP) — as an editable, layered CoDesign design or `.imgly` file; when asked to layerize, decompose, de-flatten or "make editable" an image; or when splitting an image into separate layers with live, editable text.

소스 정보

저장소
imgly/codesign
최근 소스 활동
2026년 10월 20일 21:27
감지된 SKILL.md 언어
영어
스타
43
포크
1

설치 방법

기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.

소스 파일 검토

설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.

SKILL.md 표시 중

SKILL.md
소스 지침 · 읽기 전용 미리보기
name
layerize
description
Use when rebuilding a flat raster image — an ad, banner, social post, poster or other creative (PNG / JPEG / WebP) — as an editable, layered CoDesign design or `.imgly` file; when asked to layerize, decompose, de-flatten or "make editable" an image; or when splitting an image into separate layers with live, editable text.
requires
asset_generate, asset_search
argument-hint
<image> [output.imgly]
# layerize Rebuild a source image as an editable CoDesign design: pixel layers from Seedream's layer decomposition, text rebuilt as real, editable text. ## Inputs - **Source image** — the file the user points at. - **Output path** — where the `.imgly` deliverable goes. If the user named none, use the source's path with the extension replaced by `.imgly`. Keep intermediate files (layer metadata, comparison renders, cut-outs) out of the output location. ## Stage 1 — Layers (Seedream) Call `asset_generate` — **one successful call per image**: - `model`: `bytedance/seedream-5-pro-layerize` - `image_uris`: `[uri]` — the source image, added to the workspace with `asset_add({ source: { path } })` - An image under 512 × 512 pixels is refused: upscale it first (`../models/upscalers.md`), one more paid generation, and pass the upscaled result's `id`. - `prompt`: exactly what the `models` skill prescribes for this model. Read `../models/bytedance-seedream.md` before the call — it also explains the result (which asset is the background, why cut-outs come back rescaled, how bounding boxes are written). **Never retry a call that may have generated.** If it times out, find its output with `asset_search({ sourceId: 'ly.img.workspace.images' })` (newest first): the images created together with the source's dimensions or smaller, the full-size one being the background. If it returns an error instead, check the same way first; only when none of its output is in the workspace did it not run — fix the cause the error names and call it again. After the third failure, stop: build nothing, report the errors with their `gw_…` request ids, and ask the user how to proceed. Seedream is not optional: no other model and no local cut-outs replace it. Save the returned `metadata` (layer names, z order, bounding boxes) as soon as you have it. Place the layers with this `edit` code first — the page at the background's size, the background, then every cut-out at its bounding box. Paste the whole `asset_generate` result as `RESULT`: ```js const result = RESULT; const layers = result.metadata.find((m) => m.type === 'layers').data.layers; const [bg, ...cutouts] = result.assets; const width = Number(bg.meta.width); const height = Number(bg.meta.height); const [existing] = await engine.design.findByType('page'); const [scene] = await engine.design.findByType('scene'); const page = existing ?? (await engine.design.create( { type: 'page', props: { width, height } }, { parent: scene } )); await engine.design.setProps(page, { width, height }); const image = (name, uri, [x0, y0, x1, y1]) => engine.design.create( { type: 'graphic', name, props: { position: { x: x0, y: y0 }, width: x1 - x0, height: y1 - y0, shape: { type: 'rect' }, fill: { type: 'image', uri }, contentFill: { mode: 'Contain' } } }, { parent: page } ); await image('background', bg.id, [0, 0, width, height]); for (const [i, asset] of cutouts.entries()) { const layer = layers[i + 1]; const box = layer?.bounding_box?.absolute; if (box) await image(layer.name || `layer-${i + 1}`, asset.id, box); } return { type: 'text', text: JSON.stringify({ page, layers: layers.map((l) => l.name) }) }; ``` Then handle Seedream's layers as follows (its output is not trustworthy as-is): - Every layer sits at its bounding box; cut-outs come back rescaled, and `contentFill: Contain` fits each one into its box. If the bounding boxes are missing, find each layer's scale and position by matching it against the original. - Drop Seedream's text layers; text is rebuilt in stage 2. Check that the background no longer shows the text. If it still does, inpaint it. - Inventory: every visible element must be in exactly one layer. - Drop duplicate layers. - Cut any element Seedream missed straight from the original (take the alpha from the difference between the original and the composite). - A part that sits in front of another object (e.g. a hand holding a product) may be its own layer, grouped with the object it belongs to. - Background: keep the original pixels wherever no element covers them, and color-match the filled-in areas to the original. ## Stage 2 — Text (you do the vision pass yourself) For each visible text block, record: - exact string with line breaks - role (headline / sub / body / cta / legal / price) - pixel bounding box and alignment - cap height and line pitch in px - font characteristics (serif/sans/script, width, weight, italic, caps) - fill, stroke and shadow colors as hex - whether it sits on a shape Rules: - Ignore text printed on products, packaging, labels, barcodes or logos. - Keep a visually coherent block as ONE entry: a three-line headline is one block, not three. - Transcribe literally; write "unknown" instead of guessing. Set each block as real, editable text: - closest Google Font (name a fallback too) - uppercase through the text case property (`text.case: 'Uppercase'`), not typed capitals - font size derived from the measured cap height - letter spacing (`text.letterSpacing`, a factor) and line height (`text.lineHeight: { visual }`) fitted to the measured line widths and line pitch - shadow (`dropShadow`) or stroke tuned to match the original - a button or chip keeps its shape as a separate layer under the text **Matching the original beats CoDesign's typography lint:** keep the original's tracking and leading even when the lint warns about them. ## Build - One page at the source's pixel size. - Layers from back to front: background, scene groups, logo, text. - Give every layer a descriptive name (`background`, `left-figure`, `product-can`, `logo-…`, `headline-…`). - Group each scene's layers together, and group the text blocks. ## Acceptance Compare against the original: place the source image once more as the top layer, at the page's size, with `blend: { mode: 'Difference' }`, and `preview` it. Where the rebuild matches, the preview is black; every bright shape is a difference — a missing or doubled element, text off its baseline, a wrong color. Then destroy that layer. Check with a PNG export (`export({ format: 'png' })`) compared against the original. Fix and re-export until every point holds: - text baselines within ±2 px, line widths within ±2 % - text shadow visually matches the original - average absolute pixel difference below 10/255 - no element missing, no element appearing twice - named layers, grouped per scene Then run the judge loop against the source (`../judge/SKILL.md`), export with `export({ format: 'imgly', outPath: '<output path>' })`, and report: - the layer list - what Seedream got wrong and how it was fixed - where the intermediate files are
GitHub에서 보기