# GPT Image 生成与编辑
> GPT Image 2、Sunburst 与 Flare 的两种接入方式:统一媒体任务,以及直接 Images API 的 JSON 参考图、Base64 取图和能力边界。
三款型号都支持[统一图片任务](media-images.md):使用 `POST /media/v1/images/generations`,通过 `references` 选择参考图编辑,返回 `media.task`;使用 `wait` 等待或按任务 ID 查询,再从 `artifacts[]` 下载结果。完整参数和文生图、单图、双图编辑请求见该页。
本页下文保留直接 Images API 的接入方式,响应为同步 JSON 图片,不创建统一任务。其图片格式、尺寸及效果说明来自 2026-10-15 的已有结果;本次统一任务适配的离线检查不代表重新完成真实 Provider 验收。
| 选择 | 统一媒体任务 | 直接 Images API |
| --- | --- | --- |
| 提交 | `/media/v1/images/generations` | `/v1/images/generations` 或 `/v1/images/edits` |
| 参考图 | `references`,支持平台 `file_id` 与合法 URL/Data URL | 编辑请求的 `images[].image_url`,本页使用 Data URL |
| 厂商参数 | `provider_options.openai` 中已声明的选项 | 顶层字段,按本页直接接口说明 |
| 响应与取图 | `media.task`、`artifacts[]`;查询原任务并下载产物 | `data[].b64_json`,解码图片 |
| 等待与恢复 | `wait=0..50`、`Idempotency-Key`、`GET /media/v1/tasks/{id}` | 没有统一任务与幂等重放保证,结果未知时核对原调用 |
两种入口的请求字段和响应不能混用。统一任务接口的当前限制以[图片生成](media-images.md#media-images-h-eeced450)为准;直接接口不因新增任务适配而停用。
## 地址、鉴权与型号
Base URL:`https://platform.sgt.site/v1`
请求使用 `Authorization: Bearer YOUR_VIRTUAL_KEY` 和 `Content-Type: application/json`。虚拟密钥与网关地址的设置见[地址与鉴权](access.md)。
| 方法 | 相对路径 | 用途 | 当前核对的结果 |
| --- | --- | --- | --- |
| POST | `/images/generations` | 文生图 | JSON,图片在 `data[].b64_json` |
| POST | `/images/edits` | 根据一张或多张参考图编辑 | JSON,输出是独立的新图片 |
使用下列完整模型 ID;当前配置没有把它们映射为其他调用名称。每个型号均已核对到生成和编辑的完整图片结果。
| 模型 ID | 文生图 | 参考图编辑 | 选择说明 |
| --- | --- | --- | --- |
| `gpt-image-2` | 已有完整图片结果 | 已有完整图片结果 | 基础文生图与单图编辑示例使用此 ID |
| `gpt-image-2.5-sunburst` | 已有完整图片结果 | 已有完整图片结果 | 保留完整后缀,不能简写为 `gpt-image-2.5` |
| `gpt-image-2.5-flare` | 已有完整图片结果 | 已有完整图片结果,含双参考图 | 多图编辑示例使用此 ID |
调用前仍须在[通用模型目录](models.md#models-text-list)核对当前虚拟密钥可见的 ID。平台已配置不等于每个企业都已授权;不根据型号名字推断质量、速度或价格高低。
下文示例使用 `/v1/images/*` 直接路径。需要任务查询时,从一开始使用[统一任务请求](media-images.md#media-images-gpt-generate),不能用 `/media/v1/tasks/{id}` 查询直接同步响应。此处不提供 Chat Completions 或 Responses `image_generation` 工具入口。
## 共有生成参数
下表区分请求意图与实际输出。已有结果证明基本生成和参考图编辑可用,不代表每个兼容字段都被上游执行。
| 字段 | 类型 | 必填或省略行为 | 说明 |
| --- | --- | --- | --- |
| `model` | string | 必填 | 使用上表完整 ID |
| `prompt` | string | 示例必填 | 描述画面或编辑目标、需要保留的内容;不套用其他型号的字符上限 |
| `n` | integer | 网关省略时按 1 处理;本页显式传 1 | 期望输出张数;不承诺多张生成的厂商上限,不用请求值代替实际结果数量 |
| `size` | string | 可选,省略时由当前渠道处理 | 已有请求使用 `auto`、`1024x1024`、`1152x2048` 等;用小写 `x`。不是严格像素尺寸保证,输出需读取实际文件 |
| `quality` | string | 可选,省略时由当前渠道处理 | 已有请求使用 `auto`、`medium`;不从旧型号推断完整枚举或默认值,返回值也不必与请求相同 |
| `background` | string | 可选 | 本页示例使用已核对请求中的 `opaque`;不据此承诺透明输出 |
当前核对的图片均为 PNG Base64。已有请求即使设置 `response_format=url`,也返回 `b64_json`,不能依赖此参数获得下载链接。其他选项的边界见下文;网关能保留字段不等于当前模型会执行其语义。
## 文生图:JSON 请求与取图
HTTP 失败时 curl 返回非零退出码,错误正文保存在响应文件中。HTTP 200 后仍需检查图片字段:
```bash
curl --fail-with-body -sS -X POST 'https://platform.sgt.site/v1/images/generations' \
-H 'Authorization: Bearer YOUR_VIRTUAL_KEY' \
-H 'Content-Type: application/json' \
--data '{
"model": "gpt-image-2",
"prompt": "一只蓝色陶瓷杯,浅灰背景,柔和自然光",
"n": 1,
"size": "auto",
"quality": "auto",
"background": "opaque"
}' --output image-response.json
```
Sunburst 示例同样使用完整 ID;`size` 是期望值:
```bash
curl --fail-with-body -sS -X POST 'https://platform.sgt.site/v1/images/generations' \
-H 'Authorization: Bearer YOUR_VIRTUAL_KEY' \
-H 'Content-Type: application/json' \
--data '{"model":"gpt-image-2.5-sunburst","prompt":"蓝色陶瓷杯产品图,简洁背景","n":1,"size":"1024x1024"}' \
--output image-response.json
```
响应结构示意,图片和数值均为占位说明,不是用户数据,也不保证每次出现全部字段:
```json
{
"created": 1792022400,
"data": [{"b64_json": "BASE64_IMAGE_BYTES", "generation_id": "EXAMPLE_GENERATION_ID"}],
"size": "941x1672",
"quality": "medium",
"background": "opaque",
"output_format": "png",
"usage": {"input_tokens": 17, "output_tokens": 1024, "total_tokens": 1041}
}
```
不要把 Base64 当 URL,也不要把请求尺寸、格式直接写成产物事实。已有结果中,请求尺寸和实际图片像素不同;有固定尺寸要求时,先读取图片真实宽高,再在应用侧缩放或裁剪。
将下列脚本保存为 `gpt_download.py`,运行 `python gpt_download.py` 解码 `image-response.json`。脚本检查空结果与非法 Base64,遍历全部图片并按文件头命名,未知格式保留 `.bin`。
**完整脚本 `gpt_download.py`**
```python
import base64
import json
from pathlib import Path
def save_images(result, folder="output/gpt-images"):
if result.get("error"):
raise RuntimeError("请求报错;保留响应与请求关联 ID 核对")
images = result.get("data") or []
if not images:
raise RuntimeError("响应没有最终图片;不要自动重新生成")
folder = Path(folder)
folder.mkdir(parents=True, exist_ok=True)
saved = []
for index, item in enumerate(images):
encoded = item.get("b64_json")
if not isinstance(encoded, str) or not encoded:
raise RuntimeError(f"第 {index} 项缺少 b64_json")
# 当前核对结果为纯 Base64;兼容带 Data URI 前缀的返回。
if encoded.startswith("data:"):
header, separator, encoded = encoded.partition(",")
if not separator or not header.endswith(";base64"):
raise RuntimeError("非法图片 Data URI")
try:
data = base64.b64decode(encoded, validate=True)
except (ValueError, TypeError) as error:
raise RuntimeError("图片 Base64 不完整或非法") from error
if not data:
raise RuntimeError("图片字节为空")
extension = ".bin"
if data.startswith(b"\x89PNG\r\n\x1a\n"):
extension = ".png"
elif data.startswith(b"\xff\xd8\xff"):
extension = ".jpg"
elif data[:4] == b"RIFF" and data[8:12] == b"WEBP":
extension = ".webp"
target = folder / f"image-{index}{extension}"
partial = Path(str(target) + ".part")
partial.write_bytes(data)
partial.replace(target)
saved.append(target)
if extension == ".bin":
print("格式未知,保留原字节供识别:", target)
return saved
if __name__ == "__main__":
result = json.loads(Path("image-response.json").read_text(encoding="utf-8"))
print("已保存:", save_images(result), ";请另行确认图片宽高和可读性")
```
## 参考图编辑:JSON 与 multipart
当前核对到的三款型号编辑请求使用 JSON `images[].image_url`;单图、双图都已有完整结果。编辑不覆盖输入文件,返回新图片。
| 字段 | 类型 | 必填或出现条件 |
| --- | --- | --- |
| `images` | object[] | 编辑必填,至少一张;本页演示单图和双图,不承诺其他型号文档中的最大张数 |
| `images[].image_url` | string | 每张图必填,示例使用图片 Data URL;单图为 PNG,双图为 JPEG/WebP,MIME 前缀必须与实际文件一致 |
| `model`、`prompt`、`n`、`size` | 同上表 | `prompt` 写清保留和修改内容;`n` 是输出张数,不是输入图数 |
下列 `BASE64_INPUT_PNG` 替换为自己的 PNG 图片完整 Base64。不要把文件路径、平台 `mf_` 文件 ID、素材 ID 或其他任务 ID 放进 `image_url`。
```bash
curl --fail-with-body -sS -X POST 'https://platform.sgt.site/v1/images/edits' \
-H 'Authorization: Bearer YOUR_VIRTUAL_KEY' \
-H 'Content-Type: application/json' \
--data '{
"model": "gpt-image-2",
"prompt": "把参考图中的杯子改成红色,保留形状、光照和背景",
"images": [{"image_url":"data:image/png;base64,BASE64_INPUT_PNG"}],
"n": 1,
"size": "1152x2048"
}' --output image-response.json
```
双图编辑示例使用 `gpt-image-2.5-flare`;这里按已核对的输入类型使用 JPEG 与 WebP。两个占位值分别替换为相应文件的 Base64,按数组顺序在 prompt 中引用:
```bash
curl --fail-with-body -sS -X POST 'https://platform.sgt.site/v1/images/edits' \
-H 'Authorization: Bearer YOUR_VIRTUAL_KEY' \
-H 'Content-Type: application/json' \
--data '{
"model": "gpt-image-2.5-flare",
"prompt": "把第一张图中的蓝色杯子放到第二张图的桌面上,保留杯子外观",
"images": [
{"image_url":"data:image/jpeg;base64,BASE64_CUP_JPEG"},
{"image_url":"data:image/webp;base64,BASE64_TABLE_WEBP"}
],
"n": 1,
"size": "1144x2048"
}' --output image-response.json
```
用同一个 `gpt_download.py` 保存结果。JSON `images` 与 multipart `image`/`image[]` 输入格式不同;虽然网关有 multipart 处理通路,当前样本不足以把它、遮罩或 `input_fidelity=high` 写成上述三款型号的已确认能力,本页使用已核对过的 JSON 输入。
## Python SDK
可以使用支持 Images API 的官方 `openai` 包调用生成接口,模型仍填写平台实际 ID。`max_retries=0` 关闭 SDK 自动重试,避免结果未知时自动提交第二笔生成;超时是客户端设置。`gpt_download.py` 放在同一目录。
```python
import os
from openai import OpenAI
from gpt_download import save_images
client = OpenAI(
base_url="https://platform.sgt.site/v1",
api_key=os.environ["API_KEY"],
timeout=300.0,
max_retries=0,
)
result = client.images.generate(
model="gpt-image-2",
prompt="一只蓝色陶瓷杯,浅灰背景,产品摄影",
n=1,
size="auto",
quality="auto",
background="opaque",
)
print(save_images(result.model_dump()))
```
## 透明背景与输出格式
当前核对结果为 PNG,不能据此承诺 `output_format=jpeg/webp`、`output_compression` 或 `background=transparent` 一定生效。需要指定格式或透明通道时,先核对当前渠道能力;应用转换格式必须真正解码和重新编码,改扩展名不构成转换。
## 遮罩:局部编辑
本页已核对的是参考图加文字编辑。`mask` 与 `input_fidelity` 的效果、可接受值和默认值尚未在当前三个型号上确认;不套用旧型号的 low/high 表,也不承诺透明像素遮罩的执行效果。保留源图,返回的是新产物。
## 流式与中间图片
当前核对的生成、编辑结果均为同步 JSON。网关存在 SSE 转发与兼容包装,但这不能证明当前三个型号支持 `stream=true`、`partial_images` 或固定事件序列。本页不提供未经核实的流式预览请求,使用已确认的同步流程读取 `data[].b64_json`。
## 响应、用量与排错
| 响应字段 | 类型与出现条件 | 含义 |
| --- | --- | --- |
| `created` | integer,上游提供时 | Unix 秒;缺失不当作 0 |
| `data` | array,取得图片时 | 遍历实际图片列表;缺失或空数组不算取得图片 |
| `data[].b64_json` | string,有图片时 | Base64 文件字节;解码后再识别真实格式 |
| `data[].generation_id` | string,可选 | 上游生成标识,仅保留用于关联;不是平台任务 ID,没有本页承诺的恢复接口 |
| `size` | string,可选 | 上游回报尺寸;用实际文件像素宽高确认,不能用请求值代替 |
| `quality` / `background` / `output_format` | string,可选 | 上游报告值;缺失表示未知,不补成请求值或旧型号默认值 |
| `usage` | object,可选 | 上游用量,不是人民币金额,不能单凭它确认结算完成 |
| `usage.input_tokens` / `output_tokens` / `total_tokens` | integer,可选,单位 token | 缺失不等于 0,输出 token 不是图片张数 |
| `usage.input_tokens_details` | object,可选 | 若提供,`text_tokens`/`image_tokens` 为输入量拆分;不按字段名称推断计价方式 |
平台费用以实际权威账单为准。保留 `X-Oneapi-Request-Id` 响应头与必要错误信息,不公开密钥、图片 Base64 或用户内容。
本入口没有 `media.task` 的账务状态、异步查询、取消和幂等重放保证。超时、断连、5xx、非法 Base64、空结果或客户端无法打开图片时,先核对原调用记录,不自动重复 POST;重复提交可能产生另一笔生成和费用。
| 情况 | 下一步 |
| --- | --- |
| 400 参数或素材错误 | 检查完整模型 ID、JSON 字段、图片编码与请求大小,不套用其他型号的参数表 |
| 401 / 403 | 核对虚拟密钥、模型授权及预算权限;`gpt-image-2.5` 不等于带完整后缀的两个型号 |
| 413 | 减小输入图片与整体请求体,Base64 比原始文件更大 |
| 429 | 查看限流反馈,不自动无限重提 |
| 5xx、断连、空结果或图片不完整 | 保存关联 ID 和已有响应,核对原调用,不能直接判断没有生成或没有收费 |
| 图片尺寸与请求不同 | 以实际宽高为准,有固定尺寸要求时在应用侧处理 |
需要统一任务查询和幂等恢复时,三款型号均可使用[图片生成](media-images.md)中的统一请求;不能把其任务字段直接加入本页的同步请求。