无限画布无限画布
GPU API工具箱 API 文档Proxy Base URL(画布内部)图片类

FLUX.2 Klein 精准换脸

FLUX.2 Klein 精准换脸 GPU API 请求、输入顺序、流程与返回说明

文档更新时间:2026年09月08日 12时53分18秒(UTC+8)

FLUX.2 Klein 精准换脸

最后更新:2026-09-07

项目值
modelface-swap
图片数量2 张
输入顺序图片1:目标底图;图片2:身份来源图
类型单工作流

工作流

FLUX.2 Klein 精准换脸后进入 SeedVR2 最终放大。需要肤色和头身比例修正时选择 face-swap-pro,它会在放大前开启 Krea2 Identity Edit 局部融合。

创建异步任务

curl -X POST "$BASE_URL/api/proxy/v1/images/edits/tasks" \
  -H "Cookie: ic_session=$IC_SESSION" \
  -H "X-IC-Operation-ID: $(uuidgen)" \
  -F "model=face-swap" \
  -F "prompt=保持目标图构图并自然融合" \
  -F "image=@target.png" \
  -F "image=@reference.png"

image 字段顺序不可交换。创建成功返回 id 和 status;使用 POST /api/proxy/v1/images/tasks/{id} 轮询,完成后从 GET /api/proxy/v1/images/tasks/{id}/content?index=0 下载图片。

完整 Python 调用

下面代码可直接保存为 call_face_swap.py。先执行 pip install requests,再设置 BASE_URL、IC_SESSION,并把示例图片放到脚本同目录。代码会创建任务、持续轮询并下载最终图片。

import mimetypes
import os
import time
import uuid
from contextlib import ExitStack
from pathlib import Path

import requests

BASE_URL = os.environ.get("BASE_URL", "https://ic.xshow.live").rstrip("/")
IC_SESSION = os.environ["IC_SESSION"]
MODEL = "face-swap"
POLL_SECONDS = 3
TIMEOUT_SECONDS = 6 * 60 * 60

session = requests.Session()
session.cookies.set("ic_session", IC_SESSION)


def mime(path: str) -> str:
    value = mimetypes.guess_type(path)[0]
    if not value:
        raise ValueError(f"无法识别媒体 MIME: {path}")
    return value


def checked(response: requests.Response) -> requests.Response:
    if not response.ok:
        raise RuntimeError(f"HTTP {response.status_code}: {response.text[:1000]}")
    return response


with ExitStack() as stack:
    files = [
        ("image", (Path("target.png").name, stack.enter_context(open("target.png", "rb")), mime("target.png"))),
        ("image", (Path("reference.png").name, stack.enter_context(open("reference.png", "rb")), mime("reference.png")))
    ]
    created = checked(session.post(
        f"{BASE_URL}/api/proxy/v1/images/edits/tasks",
        headers={"X-IC-Operation-ID": str(uuid.uuid4())},
        data={"model": MODEL, "prompt": "保持目标图构图并自然融合"},
        files=files,
        timeout=300,
    )).json()

task_id = created.get("id") or (created.get("data") or {}).get("id")
if not task_id:
    raise RuntimeError(f"创建响应缺少任务 ID: {created}")
print("task_id:", task_id)

deadline = time.time() + TIMEOUT_SECONDS
while time.time() < deadline:
    state = checked(session.post(
        f"{BASE_URL}/api/proxy/v1/images/tasks/{task_id}",
        timeout=60,
    )).json()
    status = str(state.get("status") or (state.get("data") or {}).get("status") or "pending").lower()
    print("status:", status)
    if status == "completed":
        output = checked(session.get(
            f"{BASE_URL}/api/proxy/v1/images/tasks/{task_id}/content",
            params={"index": 0},
            timeout=600,
        ))
        Path("result.png").write_bytes(output.content)
        print("saved: result.png")
        break
    if status in {"failed", "cancelled", "canceled", "expired"}:
        raise RuntimeError(f"任务失败: {state}")
    time.sleep(POLL_SECONDS)
else:
    raise TimeoutError(f"任务 {task_id} 超过 {TIMEOUT_SECONDS} 秒仍未完成")

失败排查

  • 400:图片数量、顺序、格式或模型参数不符合要求。
  • 404:任务不存在或不属于当前账户。
  • 409:任务尚未完成,或 operation ID 与不同请求内容冲突。
  • 502:上游生成失败或返回的图片未通过解码校验。
  • 503:模型依赖或 GPU 调度能力未就绪。

On this page