feat(image): add gpt-image-2 single and multi-image workflows
This commit is contained in:
316
docs/usage.md
Normal file
316
docs/usage.md
Normal file
@@ -0,0 +1,316 @@
|
||||
# 图片生成接口指南
|
||||
|
||||
## 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. 图片接口常见问题
|
||||
|
||||
- 只传 `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`。
|
||||
|
||||
## 16. 直连测试命令
|
||||
|
||||
- 运行 `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`。
|
||||
- 如果要走 OpenAI-compatible 的 `gpt-image-2` 图生图,运行 `bash scripts/run_openai_gpt_image2_edit.sh`。
|
||||
- 如果要走多图参考生成多图,运行 `bash scripts/run_openai_gpt_image2_multi.sh`。
|
||||
- 图生图可通过环境变量传参考图:
|
||||
`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`
|
||||
Reference in New Issue
Block a user