Files
2026-04-27 14:33:50 +08:00

7.3 KiB
Raw Permalink Blame History

GPT Image 2 示例文档

本文档基于用户站 https://apicodex.xyz 的接入方式整理,包含:

  • 文生图示例
  • 带参考图示例
  • 支持的比例列表
  • 实测返回结构
  • 同步返回与异步轮询的兼容写法

接口地址

POST https://apicodex.xyz/v1/images/generations

鉴权

请求头使用 Bearer Token

headers = {
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json",
}

支持的比例

当前整理到的 size 比例共有 13 种:

  • 1:1
  • 16:9
  • 9:16
  • 4:3
  • 3:4
  • 3:2
  • 2:3
  • 5:4
  • 4:5
  • 2:1
  • 1:2
  • 21:9
  • 9:21

说明:

  • 上述 13 种比例按你提供的接口说明整理
  • 本文档里实际请求验证过的是 16:9

建议只通过 size 传比例,不要在 prompt 里重复写比例。

文生图示例

import requests

url = "https://apicodex.xyz/v1/images/generations"

payload = {
    "model": "gpt-image-2",
    "prompt": "一只橘猫坐在窗台上看夕阳,水彩画风格",
    "n": 1,
    "size": "16:9",
}

headers = {
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json",
}

response = requests.post(url, json=payload, headers=headers, timeout=300)
print(response.json())

带参考图示例

注意:不要把参考图放进 /v1/images/generationsimage_urls 字段。当前实测该字段会被忽略,返回 usage 中 input_tokens_details.image_tokens 仍为 0。带图请求应走:

POST https://apicodex.xyz/v1/images/edits

参考图为 URL

import requests

image_url = "https://example.com/photo.jpg"
image_resp = requests.get(image_url, timeout=60)
image_resp.raise_for_status()

url = "https://apicodex.xyz/v1/images/edits"
data = {
    "model": "gpt-image-2",
    "prompt": "把这张照片变成水彩画风格",
    "size": "1:1",
}
files = [
    ("image[]", ("photo.jpg", image_resp.content, image_resp.headers.get("Content-Type") or "image/jpeg")),
]

headers = {
    "Authorization": "Bearer <token>",
}

response = requests.post(url, data=data, files=files, headers=headers, timeout=300)
print(response.json())

参考图为 base64

import requests
import base64

url = "https://apicodex.xyz/v1/images/edits"

data = {
    "model": "gpt-image-2",
    "prompt": "把这张照片变成水彩画风格",
    "size": "1:1",
}
image_bytes = base64.b64decode("iVBORw0KGgoAAAANSUhEUgAA...")
files = [
    ("image[]", ("reference.png", image_bytes, "image/png")),
]

headers = {
    "Authorization": "Bearer <token>",
}

response = requests.post(url, data=data, files=files, headers=headers, timeout=300)
print(response.json())

多张参考图

import requests

url = "https://apicodex.xyz/v1/images/edits"

data = {
    "model": "gpt-image-2",
    "prompt": "把这两张照片融合成一张海报",
    "size": "4:3",
}
files = [
    ("image[]", ("photo-a.jpg", open("photo-a.jpg", "rb"), "image/jpeg")),
    ("image[]", ("photo-b.png", open("photo-b.png", "rb"), "image/png")),
]

headers = {
    "Authorization": "Bearer <token>",
}

try:
    response = requests.post(url, data=data, files=files, headers=headers, timeout=300)
    print(response.json())
finally:
    for _, file_tuple in files:
        file_tuple[1].close()

实测结果

本仓库在 2026-04-22America/Los_Angeles对以下请求做了真实测试

{
  "model": "gpt-image-2",
  "prompt": "一只橘猫坐在窗台上看夕阳,水彩画风格",
  "n": 1,
  "size": "16:9"
}

实测结论:

  • 请求返回 HTTP 200
  • size: "16:9" 被接口接受
  • 当前实测返回是“同步结果”,不是 task_id
  • 顶层字段为 createddata
  • data[0] 中包含 b64_jsonrevised_prompt
  • 本次实测的 revised_prompt黄昏里的橘猫窗台景
  • 本次解码后的样例图尺寸为 1196x1315,没有严格匹配 16:9

实测返回结构可概括为:

{
  "created": 1776919131,
  "data": [
    {
      "b64_json": "<base64 image data>",
      "revised_prompt": "黄昏里的橘猫窗台景"
    }
  ]
}

本次测试产物已保存到仓库临时目录:

  • tmp/imagegen/gpt-image-2-16-9-response.json
  • tmp/imagegen/gpt-image-2-16-9-sample.png

同步返回时的取图方式

如果接口直接返回 b64_json,可以这样保存图片:

import base64
import requests

url = "https://apicodex.xyz/v1/images/generations"

payload = {
    "model": "gpt-image-2",
    "prompt": "一只橘猫坐在窗台上看夕阳,水彩画风格",
    "n": 1,
    "size": "16:9",
}

headers = {
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json",
}

response = requests.post(url, json=payload, headers=headers, timeout=300)
data = response.json()

img_b64 = data["data"][0]["b64_json"]
with open("output.png", "wb") as f:
    f.write(base64.b64decode(img_b64))

异步轮询写法

你提供的说明里写的是“提交后返回 task_id,再轮询 /v1/tasks/{task_id}”。如果后续该上游切回异步模式,可以用下面这种兼容写法:

import base64
import time
import requests

url = "https://apicodex.xyz/v1/images/generations"
headers = {
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json",
}
payload = {
    "model": "gpt-image-2",
    "prompt": "a corgi astronaut on the moon, cinematic, 8k",
    "size": "16:9",
    "n": 1,
}

resp = requests.post(url, json=payload, headers=headers, timeout=300)
resp.raise_for_status()
data = resp.json()

# 情况 1直接同步返回 base64
if isinstance(data, dict) and data.get("data") and data["data"][0].get("b64_json"):
    with open("output.png", "wb") as f:
        f.write(base64.b64decode(data["data"][0]["b64_json"]))
    print("saved output.png")

# 情况 2返回 task_id需要轮询
elif isinstance(data, dict) and data.get("data", {}).get("id"):
    task_id = data["data"]["id"]
    task_url = f"https://apicodex.xyz/v1/tasks/{task_id}"

    time.sleep(10)
    while True:
        task_resp = requests.get(task_url, headers=headers, timeout=60)
        task_resp.raise_for_status()
        task = task_resp.json()

        status = task["data"]["status"]
        if status == "completed":
            print(task["data"]["result"]["images"][0]["url"][0])
            break
        if status == "failed":
            raise RuntimeError(task["data"]["error"]["message"])

        time.sleep(5)

else:
    raise RuntimeError(f"unexpected response: {data}")

如果是异步结果,取图字段

如果接口返回的是任务模式,则最终图片 URL 取值为:

data.result.images[0].url[0]

任务状态说明:

  • pending: 已提交或排队中
  • processing: 上游处理中
  • completed: 成功
  • failed: 失败

注意事项

  • 单张图接口耗时可能较长,建议客户端超时至少设到 300s
  • 本次实测中,size: "16:9" 虽然被接口接受,但返回图片尺寸并未严格命中 16:9;如果你的业务依赖固定画幅,建议在下载后自行校验并按需裁切
  • 如果使用异步模式,首次轮询建议在提交后等待 10~20
  • 轮询间隔建议 3~5 秒,不要毫秒级高频轮询
  • 建议失败时做有限次重试,尤其是 TLS 或上游网络抖动场景
  • 如果服务端返回的是 b64_json,说明当前是同步模式,不需要再调 /v1/tasks/{task_id}