Files
image-generate/docs/usage.md

319 lines
9.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 图片生成接口指南
## 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`
- 这两个 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`