Skip to content

Qwen-Image-Edit 编辑

网关地址: https://ai.ospreyai.cn(公网) 模型: qwen_image_edit_2511_bf16 无需后端 Bearer Token

概述

使用 Qwen-Image-Edit-2511 模型,支持 Turbo 4步(Lightning LoRA)和 Native 40步两种模式,可做高质量图片编辑(换装、改背景、物体替换)。任务异步执行:提交工作流 → 轮询状态 → 下载结果。任务状态查询、结果下载等通用接口见 任务管理

前置条件: 需先通过 /api/v1/upload 上传输入图片。

bash
export GW="https://ai.ospreyai.cn"
export API_KEY="sk-your-api-key"

接口清单

用途方法路径
上传输入图片POST/api/v1/upload
提交编辑任务POST/api/v1/ai/image/generate
查询任务状态GET/api/v1/ai/tasks/{prompt_id}
下载结果文件GET/api/v1/ai/image/view/
查询队列GET/api/v1/ai/queue

提交图片编辑任务

POST /api/v1/ai/image/generate
Content-Type: application/json
Authorization: Bearer sk-xxx

1. 上传图片

bash
curl -H "Authorization: Bearer $API_KEY" -X POST "$GW/api/v1/upload" \
  -F "image=@/path/to/input.png" \
  -F "type=input"
# 返回: {"name": "input.png", "subfolder": "", "type": "input"}

2. 提交 Turbo 模式编辑(4步,推荐)

bash
curl -H "Authorization: Bearer $API_KEY" -X POST "$GW/api/v1/ai/image/generate" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": {
      "41": {"inputs": {"image": "input.png"}, "class_type": "LoadImage"},
      "83": {"inputs": {"image": "input.png"}, "class_type": "LoadImage"},
      "170:160": {"inputs": {"image": ["41", 0]}, "class_type": "FluxKontextImageScale"},
      "170:161": {"inputs": {"unet_name": "qwen_image_edit_2511_bf16.safetensors", "weight_dtype": "default"}, "class_type": "UNETLoader"},
      "170:162": {"inputs": {"clip_name": "qwen_2.5_vl_7b_fp8_scaled.safetensors", "type": "qwen_image", "device": "default"}, "class_type": "CLIPLoader"},
      "170:146": {"inputs": {"vae_name": "qwen_image_vae.safetensors"}, "class_type": "VAELoader"},
      "170:145": {"inputs": {"shift": 3.1, "model": ["170:161", 0]}, "class_type": "ModelSamplingAuraFlow"},
      "170:152": {"inputs": {"strength": 1.0, "model": ["170:145", 0]}, "class_type": "CFGNorm"},
      "170:156": {"inputs": {"pixels": ["170:160", 0], "vae": ["170:146", 0]}, "class_type": "VAEEncode"},
      "170:168": {"inputs": {"value": false}, "class_type": "PrimitiveBoolean"},
      "170:165": {"inputs": {"value": 4}, "class_type": "PrimitiveInt"},
      "170:166": {"inputs": {"value": 40}, "class_type": "PrimitiveInt"},
      "170:154": {"inputs": {"value": 1.0}, "class_type": "PrimitiveFloat"},
      "170:155": {"inputs": {"value": 4.0}, "class_type": "PrimitiveFloat"},
      "170:149": {"inputs": {"prompt": "", "clip": ["170:162", 0], "vae": ["170:146", 0], "image1": ["170:160", 0], "image2": ["83", 0]}, "class_type": "TextEncodeQwenImageEditPlus"},
      "170:147": {"inputs": {"reference_latents_method": "index_timestep_zero", "conditioning": ["170:149", 0]}, "class_type": "FluxKontextMultiReferenceLatentMethod"},
      "170:151": {"inputs": {"prompt": "Remove the jacket, keep the T-shirt underneath", "clip": ["170:162", 0], "vae": ["170:146", 0], "image1": ["170:160", 0], "image2": ["83", 0]}, "class_type": "TextEncodeQwenImageEditPlus"},
      "170:148": {"inputs": {"reference_latents_method": "index_timestep_zero", "conditioning": ["170:151", 0]}, "class_type": "FluxKontextMultiReferenceLatentMethod"},
      "170:153": {"inputs": {"lora_name": "Qwen-Image-Edit-2511-Lightning-4steps-V1.0-bf16.safetensors", "strength_model": 1.0, "model": ["170:152", 0]}, "class_type": "LoraLoaderModelOnly"},
      "170:163": {"inputs": {"switch": ["170:168", 0], "on_false": ["170:152", 0], "on_true": ["170:153", 0]}, "class_type": "ComfySwitchNode"},
      "170:164": {"inputs": {"switch": ["170:168", 0], "on_false": ["170:154", 0], "on_true": ["170:155", 0]}, "class_type": "ComfySwitchNode"},
      "170:167": {"inputs": {"switch": ["170:168", 0], "on_false": ["170:166", 0], "on_true": ["170:165", 0]}, "class_type": "ComfySwitchNode"},
      "170:169": {"inputs": {"seed": 1234567890, "steps": ["170:167", 0], "cfg": ["170:164", 0], "sampler_name": "euler", "scheduler": "simple", "denoise": 1.0, "model": ["170:163", 0], "positive": ["170:148", 0], "negative": ["170:147", 0], "latent_image": ["170:156", 0]}, "class_type": "KSampler"},
      "170:158": {"inputs": {"samples": ["170:169", 0], "vae": ["170:146", 0]}, "class_type": "VAEDecode"},
      "9": {"inputs": {"filename_prefix": "Qwen_Edit_2511", "images": ["170:158", 0]}, "class_type": "SaveImage"}
    },
    "extra_data": {}
  }'

响应:

json
{"prompt_id": "e5f6g7h8-...", "number": 101, "node_errors": {}}

关键节点参数

节点字段说明推荐值
41image输入图片文件名(需先上传)上传返回的 name
83image参考图片文件名(可同 41 = 自我编辑)上传返回的 name
170:151prompt编辑提示词(英文)
170:168valueTurbo 模式开关(false=Native 40步)false
170:165valueTurbo 步数4
170:169seed随机种子任意整数
9filename_prefix输出文件名前缀

Turbo vs Native

模式步数CFG速度质量
Turbo (Lightning LoRA)41.0~2-6s
Native404.0~15-20s更好

切换方式:将节点 170:168value 改为 true(启用 Turbo / Lightning LoRA)。

提示词推荐

  • 换装:"Have the person in image 1 wear the clothes from image 2"
  • 改背景:"Change the background of image 1 to a sunny beach"
  • 去除物体:"Remove the jacket, keep the T-shirt underneath"
  • 物体替换:"Replace the red wine with flowers"

缓存坑:若提交的工作流与历史完全相同(尤其 seed 相同),ComfyUI 会命中 execution_cached 直接返回,outputs 可能为空。提交时换个随机 seed 可避免。

Python 调用示例

python
import json, time, urllib.request

GW = "https://ai.ospreyai.cn"
API_KEY = "sk-your-api-key"
HEADERS = {"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"}

# 1. 上传图片(参考「任务管理」页上传示例)

# 2. 提交 Turbo 编辑工作流
nodes = {
    "41": {"inputs": {"image": "input.png"}, "class_type": "LoadImage"},
    "83": {"inputs": {"image": "input.png"}, "class_type": "LoadImage"},
    # ...其余节点同上 curl 示例...
}
nodes["170:151"]["inputs"]["prompt"] = "Remove the jacket, keep the T-shirt underneath"
nodes["170:169"]["inputs"]["seed"] = 1234567890  # 避免缓存

req = urllib.request.Request(
    f"{GW}/api/v1/ai/image/generate",
    data=json.dumps({"prompt": nodes, "extra_data": {}}).encode(),
    headers=HEADERS, method="POST",
)
prompt_id = json.loads(urllib.request.urlopen(req, timeout=30).read())["prompt_id"]

# 3. 轮询 + 4. 下载(同文生图流程)
while True:
    r = urllib.request.Request(f"{GW}/api/v1/ai/tasks/{prompt_id}", headers=HEADERS)
    task = json.loads(urllib.request.urlopen(r, timeout=15).read())[prompt_id]
    if task["status"].get("completed"):
        break
    time.sleep(5)

for out in task["outputs"].values():
    for img in out.get("images", []):
        url = f"{GW}/api/v1/ai/image/view/?filename={img['filename']}&type={img['type']}&subfolder={img.get('subfolder','')}"
        req = urllib.request.Request(url, headers=HEADERS)
        open(img["filename"], "wb").write(urllib.request.urlopen(req, timeout=120).read())

常见问题

问题现象可能原因解决方案
401 UnauthorizedAPI Key 错误/未传检查 Authorization: Bearer sk-xxx
编辑效果不如预期用了 Turbo 模式切 Native 40 步(170:168=false)
任务 success 但 outputs 为空命中 ComfyUI 缓存换随机 seed 重提

详细文档见 ComfyUI Qwen 图片编辑 Skill

AI API Gateway Documentation