# 图片生成接口指南 ## 1. 环境准备 Windows PowerShell: ```powershell py -m pip install requests pillow ``` Mac / Linux Terminal: ```bash python3 -m pip install requests pillow ``` ## 2. 接口地址 `POST https://api.toskaxy.xyz/v1/images/generations` ## 3. 鉴权方式 ```http Authorization: Bearer pk_live_xxx Content-Type: application/json ``` ## 4. 支持的图片模型 - `gpt-image-1` - `gpt-image-1.5` - `gpt-image-2` ## 5. 文生图最小字段 - `model`:图片模型名称,例如 `gpt-image-2` - `prompt`:图片提示词 - `size`:输出尺寸。推荐直接传像素尺寸,例如 `4096x4096`、`4096x2304`、`2304x4096` - `resolution`:兼容字段。使用比例写法时传 `1K`、`2K`、`4K`,网关会转换成实际像素尺寸 ## 6. `gpt-image-2` 的 4K 尺寸规则 推荐写法:直接传像素。 ```json { "model": "gpt-image-2", "prompt": "draw a clean product poster", "size": "4096x4096" } { "model": "gpt-image-2", "prompt": "draw a clean product poster", "size": "4096x2304" } { "model": "gpt-image-2", "prompt": "draw a clean product poster", "size": "2304x4096" } ``` 兼容写法:比例 + `resolution`。 ```json { "model": "gpt-image-2", "prompt": "draw a clean product poster", "size": "1:1", "resolution": "4K" } { "model": "gpt-image-2", "prompt": "draw a clean product poster", "size": "16:9", "resolution": "4K" } { "model": "gpt-image-2", "prompt": "draw a clean product poster", "size": "9:16", "resolution": "4K" } ``` ## 7. 比例转换示例 - `1:1` + `4K` -> `4096x4096` - `16:9` + `4K` -> `4096x2304` - `9:16` + `4K` -> `2304x4096` - `3:4` + `4K` -> `3072x4096` - `4:3` + `4K` -> `4096x3072` ## 8. 旧图片模型的 4K 降级规则 `gpt-image-1` 和 `gpt-image-1.5` 不支持真正 4K。如果用户传 `resolution: "4K"`,网关会自动降级成上游支持的最大尺寸。 - 横图比例:`1536x1024` - 竖图比例:`1024x1536` - 方图比例:`1024x1024` ## 9. 支持的比例 `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` 建议只通过 `size` 传比例,不要在 `prompt` 里重复写比例。 ## 10. 4K 文生图完整 Python 示例 把 `API_KEY` 改成自己的密钥,保存为 `gpt_image2_generate.py` 后运行。 ```python import base64 import requests API_KEY = "pk_live_xxx" BASE_URL = "https://api.toskaxy.xyz" payload = { "model": "gpt-image-2", "prompt": "高端香水产品海报,玻璃瓶,干净背景,商业摄影,细节清晰", "n": 1, "size": "4096x4096", "quality": "high", "response_format": "b64_json", } headers = { "Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json", } resp = requests.post( f"{BASE_URL}/v1/images/generations", json=payload, headers=headers, timeout=240, ) resp.raise_for_status() data = resp.json() img_b64 = data["data"][0]["b64_json"] with open("output.png", "wb") as f: f.write(base64.b64decode(img_b64)) print("已保存 output.png") ``` ## 11. 图生图:参考图为公开 URL ```python import base64 import requests API_KEY = "pk_live_xxx" BASE_URL = "https://api.toskaxy.xyz" payload = { "model": "gpt-image-2", "prompt": "把参考图变成水彩画风格,保留主体结构", "n": 1, "size": "2048x2048", "quality": "high", "response_format": "b64_json", "image_urls": [ "https://example.com/reference.jpg" ], } headers = { "Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json", } resp = requests.post( f"{BASE_URL}/v1/images/generations", json=payload, headers=headers, timeout=240, ) resp.raise_for_status() data = resp.json() img_b64 = data["data"][0]["b64_json"] with open("output.png", "wb") as f: f.write(base64.b64decode(img_b64)) print("已保存 output.png") ``` ## 12. 图生图:参考图为本地文件 base64 把 `reference.png` 放到脚本同一个文件夹,脚本会把它转成 data URL 再提交。 ```python import base64 import requests API_KEY = "pk_live_xxx" BASE_URL = "https://api.toskaxy.xyz" REFERENCE_FILE = "reference.png" with open(REFERENCE_FILE, "rb") as f: reference_b64 = base64.b64encode(f.read()).decode("utf-8") payload = { "model": "gpt-image-2", "prompt": "基于参考图生成一张高端产品海报,干净构图,中文界面可用", "n": 1, "size": "4096x2304", "quality": "high", "response_format": "b64_json", "image_urls": [ f"data:image/png;base64,{reference_b64}" ], } headers = { "Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json", } resp = requests.post( f"{BASE_URL}/v1/images/generations", json=payload, headers=headers, timeout=240, ) resp.raise_for_status() data = resp.json() img_b64 = data["data"][0]["b64_json"] with open("output.png", "wb") as f: f.write(base64.b64decode(img_b64)) print("已保存 output.png") ``` ## 13. 下载后校验是否为 4K ```python from io import BytesIO from PIL import Image import requests image_url = "<接口返回的图片URL>" img_bytes = requests.get(image_url, timeout=120).content img = Image.open(BytesIO(img_bytes)) print(img.size) width, height = img.size assert max(width, height) >= 3840, f"not 4K enough: {img.size}" ``` ## 14. 同步返回与异步轮询兼容写法 ```python import base64 import time import requests API_KEY = "pk_live_xxx" BASE_URL = "https://api.toskaxy.xyz" headers = { "Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json", } payload = { "model": "gpt-image-2", "prompt": "a corgi astronaut on the moon, cinematic, 8k", "size": "16:9", "resolution": "4K", "n": 1, "response_format": "b64_json", } resp = requests.post( f"{BASE_URL}/v1/images/generations", json=payload, headers=headers, timeout=240, ) 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("已保存 output.png") # 情况 2:异步任务返回 task_id elif isinstance(data, dict) and isinstance(data.get("data"), dict) and data["data"].get("id"): task_id = data["data"]["id"] task_url = f"{BASE_URL}/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}") ``` ## 15. `stream`、`partial_images`、`moderation` `gpt-image-2` 的图片接口可额外尝试下面几个字段: - `stream`:`true` / `false` - `partial_images`:整数,常见值 `1` - `moderation`:`auto` 或 `low` 示例: ```json { "model": "gpt-image-2", "prompt": "火影忍者真人版海报", "size": "3840x1280", "quality": "high", "output_format": "png", "moderation": "low", "stream": true, "partial_images": 1 } ``` 说明: - `stream=true` 时,服务端可能返回 `text/event-stream`。 - `partial_images=1` 表示在最终图之前,先推 1 张中间图。 - `moderation` 当前只观察到 `auto` 和 `low` 两个枚举值。 - 不是所有兼容网关都会真的返回 SSE;有些网关即使接受 `stream=true`,仍然返回普通 JSON。 仓库里的环境变量映射: - `IMAGE_STREAM=true` - `IMAGE_PARTIAL_IMAGES=1` - `IMAGE_MODERATION=low` 脚本处理策略: - 收到 `EventStream`:逐条解析事件,保存 `stream-events.jsonl` 和 `partials/`。 - 没收到 `EventStream`:自动回退到同步 JSON 或异步任务轮询逻辑。 ## 16. 图片接口常见问题 - 只传 `size: "16:9"` 不能保证一定是 4K;要 4K,推荐直接传 `4096x2304` 等像素尺寸。 - `gpt-image-1` 和 `gpt-image-1.5` 不支持真正 4K,网关会自动降级。 - `gpt-image-2` 的图生图不要把参考图塞进 `/v1/images/generations` 的 JSON。应改走 `/v1/images/edits`,并用 `multipart/form-data` 上传 `image` 或 `image[]`。 - 单张图可能耗时较长,客户端 `timeout` 建议至少 120 秒;4K 建议 240 秒。 - 如果返回 `b64_json`,说明当前是同步模式,不需要再轮询 `task_id`。 ## 17. 直连测试命令 - 运行 `scripts/run_figma_direct_test.sh` 会先读取当前 `.env`,再临时清空本地代理并直连 `vip.auto-code.net`。 - 它只强制 `IMAGE_REQUEST_STYLE=apicodex`、`IMAGE_SIZE=3840x2160` 和长超时,其余参数继续沿用 `.env` 和 `gpt_image2_generate.py` 的默认值。 - 每次请求会落到 `outputs/image-demo-runs/<时间戳>/`。 - 直接运行:`bash scripts/run_figma_direct_test.sh` - 只测 `https://api.aoixx.com/v1/images/generations` 时,运行 `bash scripts/run_aoixx_direct_test.sh`。 - 这两个 direct test 会自动忽略 `.env` 里的 `REFERENCE_IMAGE` 和 `MASK_IMAGE`,默认走纯生成流程。 - 如果要走 OpenAI-compatible 的 `gpt-image-2` 图生图,运行 `bash scripts/run_openai_gpt_image2_edit.sh`。 - 如果要走多图参考生成多图,运行 `bash scripts/run_openai_gpt_image2_multi.sh`。 - 这两个 OpenAI 脚本会强制 `IMAGE_REQUEST_STYLE=openai`,不会沿用 `.env` 里的 `apicodex`。 - 图生图可通过环境变量传参考图: `REFERENCE_IMAGE=./input.png`,或 `REFERENCE_IMAGE_URL=https://example.com/input.png`。 - 如需 mask,可额外传: `MASK_IMAGE=./mask.png`,或 `MASK_IMAGE_URL=https://example.com/mask.png`。 - 多图参考推荐两种写法: `REFERENCE_IMAGE_1=./a.png`、`REFERENCE_IMAGE_2=./b.png`,或 `REFERENCE_IMAGES='["./a.png","./b.png","./c.png"]'`。 - 多图输出用 `IMAGE_N=3` 控制,未设置时默认等于参考图数量。 - 示例: `REFERENCE_IMAGE=./input.png IMAGE_PROMPT="改成极简白底产品海报" bash scripts/run_openai_gpt_image2_edit.sh`