7.3 KiB
7.3 KiB
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:116:99:164:33:43:22:35:44:52:11:221:99: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/generations 的 image_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-22(America/Los_Angeles)对以下请求做了真实测试:
{
"model": "gpt-image-2",
"prompt": "一只橘猫坐在窗台上看夕阳,水彩画风格",
"n": 1,
"size": "16:9"
}
实测结论:
- 请求返回
HTTP 200 size: "16:9"被接口接受- 当前实测返回是“同步结果”,不是
task_id - 顶层字段为
created和data data[0]中包含b64_json和revised_prompt- 本次实测的
revised_prompt为黄昏里的橘猫窗台景 - 本次解码后的样例图尺寸为
1196x1315,没有严格匹配16:9
实测返回结构可概括为:
{
"created": 1776919131,
"data": [
{
"b64_json": "<base64 image data>",
"revised_prompt": "黄昏里的橘猫窗台景"
}
]
}
本次测试产物已保存到仓库临时目录:
tmp/imagegen/gpt-image-2-16-9-response.jsontmp/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}