본문으로 건너뛰기

API로 이미지를 레이어 분해하기: Seedream 5.0 Flash 대 Pro

이미지 한 장을 깔끔한 베이스 이미지와 최대 16장의 투명 PNG 레이어로 바꾸는 방법. 실제 결과, bbox 문법, 비용, 레이어 다시 합치기.

작성자
SpicyAPI Engineering
발행
읽는 시간
약 12분
수정
LATE SHIFT 포스터를 레이어별로 분해한 모습. 깨끗한 비 오르는 거리, 다이너, 타이틀, 태그라인, 빨간 트렁치코트를 입은 여성, ADMIT ONE 티켓이 각각 금색 테두리 안에 담겨 있다

한 줄 답변: 이미지 한 장을 보내면 보정된 베이스 이미지(분리한 요소를 지우고 배경을 채운 이미지)와 요소 하나당 한 장씩 최대 16장의 투명 PNG 레이어를 돌려받습니다. 모든 레이어에는 name과 boundingBox가 붙으므로 레이어를 원래 위치에 다시 쌓을 수 있습니다. SpicyAPI는 이를 Seedream 5.0 Flash에서 어떤 해상도든 출력 이미지당 $0.026에, Seedream 5.0 Pro에서 이미지당 $0.042(1K, 1.5K) 또는 $0.084(2K, auto)에 실행합니다. 먼저 Flash로 시작하세요. 가격이 더 싸고, 우리 테스트에서 성인 입력 범주를 모두 문제없이 처리했습니다. Pro는 더 비싸고, 성인 두 명의 친밀한 장면을 담은 이미지는 거부합니다.

30초 요약

  • 출력: 인덱스 0은 베이스 이미지이고 그다음부터 레이어가 나옵니다. 레이어는 항상 투명 PNG이며, output_format은 베이스 이미지만 바꿉니다(JPEG 또는 PNG).
  • 상한과 과금: 한 번 실행할 때 최대 17장(베이스 이미지 + 16개 레이어)이고, 반환된 이미지에 대해 과금되며 베이스 이미지도 포함됩니다. 작업이 승인되면 17장 가격을 잠시 잡아두고, 실제 개수가 확인되면 차액을 환불합니다.
  • 프롬프트는 선택 사항. 쓰지 않으면 모델이 주요 요소를 고릅니다. 쓰면 이름으로 적은 것만 분리합니다. 레이어 개수를 정하는 설정은 없습니다.
  • 즉시 되지는 않음: 두 모델 모두 한 번 실행에 약 45~100초 걸립니다.
  • 실행이 끝나면 파일을 자신의 스토리지로 복사하세요.

실제로 어떻게 보이는가

출발점은 Seedream 5.0 Flash로 생성한 포스터였습니다.

LATE SHIFT 포스터. 빨간 트렁치코트를 입은 여성이 빨간 네온 사인 아래 다이너 앞에서 종이컵을 들고 있다. 상단에 크림색 세리프 타이틀, 오른쪽 아래에 노란 ADMIT ONE 티켓 스텁

Flash, 프롬프트 없이

resolution을 auto로 두고 프롬프트 없이 포스터를 보냈습니다. 8장이 돌아왔습니다. 베이스 이미지와 7개 레이어로, 다이너, 멀리 있는 자동차, 빨간 네온 사인, 빨간 트렁치코트를 입은 여성, 태그라인, LATE SHIFT 타이틀, ADMIT ONE 티켓 스텁이었습니다.

LATE SHIFT 결과의 레이어를 펼친 모습. 비 오르는 거리의 베이스 이미지와 7개 레이어(다이너, 자동차, 네온, 여성, 태그라인, 타이틀, 티켓)가 금색 테두리에서 부채꼴로 펼쳐져 있고 오른쪽에 번호 목록이 있다

베이스 이미지는 비 오르는 거리에서 다이너, 여성, 모든 글자가 제거되고 도로가 채워진 모습입니다. 지워진 요소 뒤에 있던 부분은 모델이 다시 그리므로 그럴듯해 보이지만 원본 픽셀은 아닙니다.

Flash의 베이스 이미지. 다이너, 여성, 모든 텍스트가 제거되고 배경이 채워진 비 오르는 밤 거리

Flash 레이어 두 장을 단독으로 보면(에디터에서 보게 되는 체스판은 그냥 투명도입니다):

단독으로 본 투명 LATE SHIFT 타이틀 레이어
단독으로 본 빨간 트렁치코트를 입은 여성의 투명 레이어

Pro, 요소 이름 지정하기

Pro에는 같은 포스터를, 다섯 개 요소를 이름으로 적은 프롬프트와 함께 1.5K로 보냈습니다:

text
Separate the LATE SHIFT title, the tagline, the woman in the red trench coat,
the diner building and the ADMIT ONE ticket stub into their own layers

6장이 돌아왔습니다. 베이스 이미지와 Diner building, Tagline text, LATE SHIFT title, Woman in red trench coat, ADMIT ONE ticket stub라는 이름의 5개 레이어였습니다. 바운딩 박스 순서대로 쌓으면 원본 포스터가 재현됩니다.

Pro 결과의 컨택트 시트. 베이스 이미지와 5장의 투명 레이어로 다이너, 태그라인, 타이틀, 여성, 티켓 스텁

Pro는 이전에 만든 향수 광고도 처리했습니다. 네 개 요소(NOIR ÉTÉ 헤드라인, 병, 금색 리본, 작은 "eau de parfum" 줄)를 이름으로 지정하니 5장을 받았습니다. 빈 검은 대리석 받침이 베이스 이미지이고, 나머지는 4개 레이어였습니다. 아무것도 다시 생성하지 않고 새 배경에서 다시 연출할 수 있는 제품 샷입니다.

Pro 향수 결과의 컨택트 시트. 빈 검은 대리석 베이스 이미지와 금색 리본, 병, 헤드라인, 작은 텍스트의 4개 레이어

Flash와 Pro 중 무엇을 쓸까

FlashPro
출력 이미지당 가격모든 해상도에서 $0.026$0.042(1K, 1.5K), $0.084(2K 및 auto)
기본 resolutionauto1.5k
이름과 박스모든 레이어에 name과 boundingBox모든 레이어에 name과 boundingBox
같은 포스터, 자동 분해7개 레이어 + 베이스 이미지8개 레이어 + 베이스 이미지
성인 대상 입력 이미지(NSFW, 강한 주제까지)허용허용
성인 두 명의 친밀한 장면허용거부, 과금 없음
프롬프트선택 사항. 쓰면 3자 이상선택 사항

기본적으로 Flash를 고르세요. 더 싸고 여기서 테스트한 성인 입력 범주를 모두 문제없이 처리했습니다. Flash의 분해에서 필요한 요소가 빠졌고 입력이 성인 두 명의 친밀한 장면이 아니라면 Pro를 고르세요(같은 장면의 가려진 버전은 정상적으로 분해됩니다). Pro에서 거부된 이미지는 일반적인 오류와 함께 실패한 작업으로 돌아오고 과금은 없습니다. 같은 이미지를 다시 시도하지 말고 Flash로 보내세요. 둘 다 이름과 박스를 제공하므로 같은 작업에 모두 적합합니다:

  • 포스터의 헤드라인을 편집해 다시 넣기;
  • 배경만 바꾸고 제품이나 인물은 그대로 유지하기;
  • 오려낸 부분을 스티커나 재사용 가능한 디자인 리소스로 만들기;
  • 한 장의 일러스트로 패럴랙스 장면이나 애니메이션 리그 만들기.

원하는 것을 이름으로 지정하는 프롬프트 작성법

프롬프트가 없으면 모델이 무엇을 요소로 볼지 스스로 정합니다. 프롬프트가 있으면 나열한 것만 분리합니다. 두 가지 습관이 결과를 예측 가능하게 만들었습니다:

  • 관심 있는 요소는 전부 이름으로 지정하세요. 짧은 명사구로 씁니다: "the LATE SHIFT title", "the woman in the red trench coat". 빠뜨린 것은 모델이 결정하므로, 옮길 대상은 반드시 이름을 적으세요. 요소를 적게 요청하면 레이어도 적어지고, 상한은 16장입니다.
  • 영역을 <bbox>로 가리키세요. 좌표는 x1 y1 x2 y2 형식이며, 이미지 크기와 상관없이 좌측 상단을 원점으로 하는 0~1000 그리드에 정규화됩니다:
text
Separate the title text <bbox>179 58 809 197</bbox> and the parrot
<bbox>330 274 641 991</bbox> into independent layers

이렇게 하면 두 대상이 닮았거나 겹친 경우도 구분할 수 있습니다. 1536×2048 이미지에서 가로로 100~900인 박스는 154~1382 픽셀을 덮습니다.

비용

반환된 이미지마다 과금되며 베이스 이미지도 1장으로 셉니다. 일반적인 포스터와 광고는 3~11장이 돌아옵니다. Flash는 $0.078~$0.286이고, Pro를 1.5K로 6장 실행하면 6 × $0.042 = $0.252입니다. 그 외에 레이어별로 과금되는 항목은 없습니다.

승인 시 잡아두는 금액은 17장 가격입니다. Flash는 $0.442, Pro는 1K 또는 1.5K에서 $0.714, 2K 또는 auto에서 $1.428입니다. 실행이 끝나면 실제 개수까지 해제됩니다. Pro에서 확실하게 분해되게 하려면 resolution을 1k 또는 1.5k로 설정하세요. auto는 2K 요율로 과금되므로, Flash 예제에서 auto를 그대로 복사한 요청은 Pro에서 두 배 비용입니다.

먼저 Playground에서 시도하세요

  1. Flash 레이어 분해 페이지를 열고 Playground 탭의 Form 뷰에 머무르세요. 실행하려면 잔액이 있는 계정으로 로그인합니다.
  2. Input image 아래에 포스터나 광고를 추가하세요(파일 또는 Asset URL).
  3. Prompt를 비워 두면 모델이 주요 요소를 고르고, 옮길 요소를 이름으로 지정할 수도 있으며, 닮은 것이 있으면 <bbox>를 붙이세요.
  4. Flash에서는 Resolution을 auto로 둔 채 모델을 실행하세요. 결과가 레이어 보기로 열리고, 레이어를 숨기거나, 레이어 한 장 또는 전부를 zip으로 내려받거나, 보이는 스택을 PNG 한 장으로 내보낼 수 있습니다. 사이트에서 만든 이미지는 레이어 분해에 바로 보낼 수 있습니다.
  5. 분해에서 뭔가 빠졌다면 같은 이미지를 Pro 페이지에서 실행하세요. auto는 2K 요율로 과금되므로, 그쪽에서는 Resolution을 1k 또는 1.5k로 두세요.

그다음 코드에서 실행하기

Python SDK(pip install spicyapi)를 설치하고, 서버 환경에서 SPICY_API_KEY를 설정한 뒤 실행하세요:

python
import uuid
from spicyapi import SpicyClient, output_assets

client = SpicyClient()  # reads SPICY_API_KEY from the environment

task = client.create_task(
    model="bytedance/seedream-5.0-flash/layer-decomposition",
    input_data={
        "image_url": "https://your-cdn.example/poster.png",
        "prompt": "Separate the LATE SHIFT title, the tagline, the woman in the red trench coat, "
                  "the diner building and the ADMIT ONE ticket stub into their own layers",
        "resolution": "auto",
        "output_format": "png",
    },
    idempotency_key=str(uuid.uuid4()),
)

print("Resume task:", task["taskId"], flush=True)
final = client.wait_for_terminal(task["taskId"])  # a run takes about 45 to 100 seconds
if final["state"] != "succeeded":
    raise RuntimeError(f"{task['taskId']} ended as {final['state']}: {final.get('errorCode')}")
assets = output_assets(final)  # assets[0] is the base plate; copy the files to your own storage now
if not assets or any(a.get("pending") or a.get("unavailable") or not a.get("url") for a in assets):
    raise RuntimeError(f"Task {task['taskId']} has no ready output; check this task before a new run")

Pro에는 "resolution": "1.5k"와 함께 bytedance/seedream-5.0-pro/layer-decomposition을 사용하세요. 원본 이미지는 10 MB 미만으로 유지하세요. 생성, 대기, 다운로드, 재시도, 콜백 본문은 tasks 가이드와 Python SDK 레퍼런스에 있습니다.

또는 Agent에게 실행시키기

분해를 어시스턴트가 실행하게 하면, 공식 도구 세 가지 모두 가격을 표시하고 유료 호출 전에 확인을 요청합니다.

  • CLI. 같은 input 객체를 input.json에 넣고 다음을 실행하세요:

``bash spicyapi tasks create --model bytedance/seedream-5.0-flash/layer-decomposition --input-file input.json --wait ``

CLI 문서를 참고하세요. npx @spicyapi/cli는 설치 없이 동작합니다.

  • MCP 서버. 어시스턴트에 MCP 서버를 추가하고 이렇게 물어보세요: "Split this poster into layers with Seedream 5.0 Flash and name the title, the tagline and the woman." spicyapi_task_create를 호출해 가격 확인에서 멈추고, 이어서 spicyapi_task_wait를 호출합니다.
  • Skill. npx skills add spicyapi-ai/spicy-skill는 Agent Skill을 설치해, 코딩 어시스턴트가 필드를 추측하지 않고 실제 모델 스키마를 읽게 합니다.

레이어를 다시 쌓기

레이어 PNG는 대개 차지하는 박스보다 해상도가 높습니다(예: 671×139 박스에 1233×256 PNG). 따라서 각 레이어를 박스 크기로 맞춘 다음 zIndex가 작은 것부터 큰 것 순으로 그리세요. Flash와 Pro 어느 쪽 출력에도 똑같이 적용됩니다.

Pillow를 사용한 Python:

python
import io
import requests
from PIL import Image

def fetch(url):
    return Image.open(io.BytesIO(requests.get(url, timeout=60).content)).convert("RGBA")

assets = output_assets(final)                      # from the finished task above
if not assets or any(a.get("pending") or a.get("unavailable") or not a.get("url") for a in assets):
    raise RuntimeError(f"Task {task['taskId']} has no ready output; check this task before a new run")
canvas = fetch(assets[0]["url"])                   # base plate, zIndex 0

for a in sorted(assets[1:], key=lambda a: a["layer"]["zIndex"]):
    box = a["layer"].get("boundingBox")
    if not box:
        continue                                   # no position: place this one by hand
    x1, y1, x2, y2 = [round(v) for v in box]
    layer = fetch(a["url"]).resize((x2 - x1, y2 - y1), Image.LANCZOS)
    canvas.paste(layer, (x1, y1), layer)           # alpha-aware paste

canvas.convert("RGB").save("recomposed.jpg", quality=95)

브라우저에서는 canvas로 똑같이 할 수 있습니다:

js
async function load(url) {
  const img = new Image();
  img.crossOrigin = "anonymous";
  img.src = url;
  await img.decode();
  return img;
}

const assets = task.data.output.assets;           // task: the finished task's JSON
const base = await load(assets[0].url);
const canvas = document.createElement("canvas");
canvas.width = base.naturalWidth;
canvas.height = base.naturalHeight;
const ctx = canvas.getContext("2d");
ctx.drawImage(base, 0, 0);

const layers = assets.slice(1).sort((a, b) => a.layer.zIndex - b.layer.zIndex);
for (const a of layers) {
  const box = a.layer.boundingBox;
  if (!box) continue;                              // no position: place this one by hand
  const [x1, y1, x2, y2] = box;
  ctx.drawImage(await load(a.url), x1, y1, x2 - x1, y2 - y1);
}

포스터 타이틀을 바꾸려면 해당 레이어를 반복문에서 빼고 같은 박스에 직접 그린 텍스트를 넣은 뒤 나머지는 그대로 두면 됩니다. 배경만 바꾸려면 assets[0]을 같은 크기의 내 이미지로 교체하세요.

이미지를 레이어로 나누는 다른 방법

이 검색에서 상위 노출되는 페이지는 대다수 크레딧 기반 브라우저 도구이며 API가 없습니다. 주요 오픈소스 대안은 Qwen-Image-Layered(Apache 2.0, 20B 파라미터)로, GPU에 직접 호스팅하거나 fal을 통해 출력 이미지당 $0.05로 호출할 수 있습니다(레이어별로 과금된다면 기본 4레이어 실행은 약 $0.20입니다). 그곳에서는 레이어 개수(기본 4개)를 정하고 이름도 위치 정보도 없는 전체 캔버스 크기의 투명 이미지를 받습니다. fal의 안전성 검사는 기본으로 켜져 있어 플래그된 입력에는 검은 이미지를 반환합니다. 레이어 수를 고정해야 하거나 자체 호스팅이 필요하면 그쪽을 고르세요. 잘라낸 레이어와 레이어별 이름과 위치, 요소를 이름으로 지정하는 프롬프트, 성인 입력 이미지를 허용해야 한다면 Seedream 레이어 분해를 고르세요. Flash에서도 이미지당 $0.026이므로 이미지 단위로는 더 저렴합니다.

FAQ

레이어는 몇 장이나 나오나요?

모델이 찾은 만큼 나오며 최대 16장에 베이스 이미지가 더해집니다. 개수를 직접 정할 수는 없습니다. 요소 이름을 적어 개수를 조절하고, 빠진 것이 있으면 이름을 넣거나 그 <bbox>를 준 뒤 다시 실행하세요. 재실행도 새 실행과 동일하게 과금됩니다.

SpicyAPI에서 만들지 않은 이미지도 분해할 수 있나요?

가능합니다. 모델 페이지의 한도 안이라면 어떤 단일 이미지든 됩니다. 깔끔하게 분해되는 포스터 재료를 만들려면 Seedream 5.0 Flash 텍스트→이미지에서 시작하세요.

결과는 재현되나요?

아닙니다. 시드가 없으므로 분해는 한 번만 실행하고 파일을 보관한 뒤 그 파일을 편집하세요.

다음 단계

이미 마음에 드는 포스터를 Flash 레이어 분해로 시도해 보세요. 뭔가 빠졌다면 같은 이미지를 Pro로 통과시키세요.

다른 언어 English · 日本語 · Deutsch · Français · Español · Português (Brasil) · Русский · Italiano · Polski

직접 해 보기

실행한 만큼만 결제하세요. 요금제도, 구독도 없습니다.

사용 모델: MiniMax H3 · ByteDance Seedance 2.0 Fast