LoopToken
图片生成

Qwen Image 2.0 Pro

qwen-image-2.0-pro 文生图接口、参数、响应、下载与计费说明

qwen-image-2.0-pro 是同步文生图模型,擅长中英文文字渲染、海报、图表、PPT 视觉稿、写实材质和复杂图文布局。

能力矩阵

能力支持情况说明
文本生成图片支持中英文提示词,单次输出 1-6 张 PNG
中英文文字渲染支持适合海报、信息图和演示文稿视觉稿
自定义尺寸支持使用 parameters.size
反向提示词、提示词改写、水印、种子支持均为可选参数
参考图片、图片编辑、multipart 上传不在稳定范围此页面的请求只接受一个文本内容项
顶层 prompt不支持文本必须位于 input.messages
流式响应不在稳定范围使用同步 HTTP 请求并等待完整 JSON 响应

接口

  • Endpoint:POST /v1/images/generations
  • Base URL:https://api.vibelab.me
  • Authorization: Bearer <your-api-key>
  • Content-Type: application/json

请求采用多模态消息 JSON:input.messages 保存提示词,parameters 保存生成选项。不要发送 multipart 表单。

参数

参数类型必填默认值范围或格式适用性与依赖
modelstring-固定为 qwen-image-2.0-pro所有请求
inputobject-包含 messages所有请求
input.messagesarray-数组内恰好 1 个元素仅支持单轮
input.messages[0].rolestring-固定为 user所有请求
input.messages[0].contentarray-数组内恰好 1 个元素只允许文本内容
input.messages[0].content[0].textstring-中英文,最多 1300 Token;超出部分可能被截断正向提示词
parametersobject{}见下列字段省略时使用模型默认值
parameters.negative_promptstring最多 500 个字符;超出部分可能被截断描述不希望出现的内容
parameters.sizestring2048*2048宽*高;总像素在 512*5122048*2048 之间宽高可自由组合,需满足总像素范围
parameters.ninteger11-6期望输出图片数
parameters.prompt_extendbooleantruetruefalse开启时会改写正向提示词,可能增加耗时
parameters.watermarkbooleanfalsetruefalse开启后在右下角添加模型水印
parameters.seedinteger随机0-2147483647相同值仅提高相对稳定性,不保证结果完全一致

尺寸限制按总像素计算,不表示宽和高必须分别落在 512-2048。以下是官方推荐的常用比例:

比例推荐尺寸
1:12048*2048
16:92688*1536
9:161536*2688
4:32368*1728
3:41728*2368

请求结构

最小请求:

{
  "model": "qwen-image-2.0-pro",
  "input": {
    "messages": [
      {
        "role": "user",
        "content": [{"text": "白底上的蓝色圆形图标"}]
      }
    ]
  }
}

完整参数:

{
  "model": "qwen-image-2.0-pro",
  "input": {
    "messages": [
      {
        "role": "user",
        "content": [{"text": "雨夜城市街角的咖啡店,写实摄影,玻璃窗上有清晰中文招牌"}]
      }
    ]
  },
  "parameters": {
    "negative_prompt": "模糊,低画质,文字扭曲",
    "size": "2048*2048",
    "n": 1,
    "prompt_extend": false,
    "watermark": false,
    "seed": 20260712
  }
}

显式尺寸:

{
  "model": "qwen-image-2.0-pro",
  "input": {"messages": [{"role": "user", "content": [{"text": "海边日落,全景摄影"}]}]},
  "parameters": {"size": "2688*1536"}
}

显式张数:

{
  "model": "qwen-image-2.0-pro",
  "input": {"messages": [{"role": "user", "content": [{"text": "极简风格的应用图标"}]}]},
  "parameters": {"n": 3}
}

中文海报:

{
  "model": "qwen-image-2.0-pro",
  "input": {
    "messages": [
      {
        "role": "user",
        "content": [{"text": "竖版夏日音乐节海报,主标题写‘向海而歌’,副标题写‘7月20日 18:00’,蓝白配色,现代排版"}]
      }
    ]
  },
  "parameters": {"size": "1536*2688", "prompt_extend": false}
}

固定种子:

{
  "model": "qwen-image-2.0-pro",
  "input": {"messages": [{"role": "user", "content": [{"text": "红色陶瓷杯,产品摄影,白色背景"}]}]},
  "parameters": {"seed": 42, "prompt_extend": false}
}

cURL

curl --fail-with-body https://api.vibelab.me/v1/images/generations \
  -H "Authorization: Bearer $LOOPTOKEN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "qwen-image-2.0-pro",
    "input": {
      "messages": [
        {"role": "user", "content": [{"text": "白底上的蓝色圆形图标"}]}
      ]
    },
    "parameters": {"n": 1}
  }'

Python

需要 Python 3.9+ 与 requests。脚本会检查状态码、解析结构化错误、遍历并下载所有图片,并从响应头或 URL 推断扩展名。

import mimetypes
import os
from pathlib import Path
from urllib.parse import urlparse

import requests

API_URL = "https://api.vibelab.me/v1/images/generations"
api_key = os.environ["LOOPTOKEN_API_KEY"]
payload = {
    "model": "qwen-image-2.0-pro",
    "input": {
        "messages": [{"role": "user", "content": [{"text": "白底上的蓝色圆形图标"}]}]
    },
    "parameters": {"n": 2},
}

response = requests.post(
    API_URL,
    headers={"Authorization": f"Bearer {api_key}"},
    json=payload,
    timeout=300,
)
try:
    body = response.json()
except ValueError:
    body = {"error": {"type": "invalid_response", "message": response.text}}
if not response.ok:
    error = body.get("error", body)
    raise RuntimeError(f"HTTP {response.status_code}: {error}")

items = [
    item
    for choice in body.get("output", {}).get("choices", [])
    for item in choice.get("message", {}).get("content", [])
    if item.get("image")
]
if not items:
    raise RuntimeError("response contained no output image URL")

for index, item in enumerate(items, start=1):
    image_response = requests.get(item["image"], timeout=120)
    image_response.raise_for_status()
    content_type = image_response.headers.get("content-type", "").split(";", 1)[0]
    extension = mimetypes.guess_extension(content_type) or Path(urlparse(item["image"]).path).suffix or ".png"
    path = Path(f"qwen-image-{index}{extension}")
    path.write_bytes(image_response.content)
    print(path)

Node.js

需要 Node.js 18+。脚本使用内置 fetch,无需额外依赖。

import { writeFile } from 'node:fs/promises';
import path from 'node:path';

const apiKey = process.env.LOOPTOKEN_API_KEY;
if (!apiKey) throw new Error('LOOPTOKEN_API_KEY is required');

const response = await fetch('https://api.vibelab.me/v1/images/generations', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${apiKey}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    model: 'qwen-image-2.0-pro',
    input: {
      messages: [{ role: 'user', content: [{ text: '白底上的蓝色圆形图标' }] }],
    },
    parameters: { n: 2 },
  }),
});

const text = await response.text();
let body;
try {
  body = JSON.parse(text);
} catch {
  body = { error: { type: 'invalid_response', message: text } };
}
if (!response.ok) {
  throw new Error(`HTTP ${response.status}: ${JSON.stringify(body.error ?? body)}`);
}

const items = (body.output?.choices ?? []).flatMap((choice) =>
  (choice.message?.content ?? []).filter((item) => item.image),
);
if (items.length === 0) throw new Error('response contained no output image URL');

const extensionFor = (contentType, url) => {
  const known = { 'image/png': '.png', 'image/jpeg': '.jpg', 'image/webp': '.webp', 'image/gif': '.gif' };
  return known[contentType.split(';', 1)[0]] ?? (path.extname(new URL(url).pathname) || '.png');
};

for (const [index, item] of items.entries()) {
  const imageResponse = await fetch(item.image);
  if (!imageResponse.ok) throw new Error(`download failed: HTTP ${imageResponse.status}`);
  const extension = extensionFor(imageResponse.headers.get('content-type') ?? '', item.image);
  const filename = `qwen-image-${index + 1}${extension}`;
  await writeFile(filename, Buffer.from(await imageResponse.arrayBuffer()));
  console.log(filename);
}

响应

成功响应示例:

{
  "output": {
    "choices": [
      {
        "finish_reason": "stop",
        "message": {
          "role": "assistant",
          "content": [
            {"image": "https://example.invalid/generated/image.png?Expires=0"}
          ]
        }
      }
    ]
  },
  "usage": {
    "image_count": 1,
    "width": 2048,
    "height": 2048
  }
}
字段类型说明
outputobject模型输出容器
output.choicesarray同步调用通常只有一个 choice
output.choices[].finish_reasonstring正常完成时通常为 stop
output.choices[].message.rolestring模型消息角色,通常为 assistant
output.choices[].message.contentarray生成内容数组;n 张图片可位于同一数组中
output.choices[].message.content[].imagestringPNG 图片的临时 HTTPS URL
usage.image_countinteger成功生成的图片数
usage.widthinteger输出宽度,像素
usage.heightinteger输出高度,像素

图片 URL 是临时资源。收到响应后应立即下载并转存;下载域名和具体有效期都不属于稳定合同,不应依赖固定域名白名单或长期可恢复性。

LoopToken 请求 ID 位于 HTTP 响应头 X-Request-Id,不会由 LoopToken 注入成功响应体。排查时应同时保存该响应头。

错误处理

LoopToken 本地错误采用统一结构:

{
  "error": {
    "message": "invalid image generation request",
    "type": "invalid_request",
    "code": "invalid_request",
    "request_id": "req_example"
  }
}
HTTP 状态error.type常见原因
400invalid_requestLoopToken 本地无法读取或解析请求,例如 JSON 无效或缺少 model
401鉴权错误API Key 缺失或无效
402insufficient_credits余额不足以预扣本次请求
403model_not_allowed当前 Key 无权使用该模型
404model_not_found模型名不存在
502upstream_error模型服务拒绝提示词、尺寸、其他参数或内容安全校验,或生成失败
503no_available_channel当前没有可处理该模型的服务资源;也可能在可重试失败后返回

error.code 当前与 error.type 相同。模型服务的非 2xx 响应会由 LoopToken 统一转换为 HTTP 502 和 upstream_error,不透出上游错误类型或文案。错误响应应同时记录 HTTP 状态、error.codeerror.messageerror.request_id。当前环境未提供可安全使用的 API 凭据,因此这些错误场景的实际响应尚未进行在线验证。

计费

按最终识别到的输出图片张数计费。请求开始时按正整数 parameters.n 预扣;省略、零或负数时按 1 张。成功响应能识别图片时按实际图片数结算;若模型服务返回 2xx,但无法识别 output.choices[].message.content[].image 而得到 Count=0,则按上述本地提交数量结算。非 2xx、没有可用服务资源或重试全部失败会全额退款。usage 仅是模型服务返回的用量信息,不是 LoopToken 的计费金额。尺寸价格键未命中时使用 default 单价。最终价格以模型列表为准。

边界

  • 只发送 JSON 文生图请求;参考图片、图片修改和 multipart 文件上传不属于此接口的稳定能力。
  • 不要使用顶层 prompt;必须使用 input.messages[0].content[0].text
  • 不要假设流式返回、异步任务 ID、Base64 图片或 OpenAI data[] 响应可用。
  • LoopToken 当前只读取 modelparameters.nparameters.size 做路由与计费,其余字段会转发给模型服务校验;参数越界可能表现为 502 upstream_error

本页内容