跳转至

GPT Image 2 图片生成

兼容 OpenAI 图片生成接口标准,可直接使用 OpenAI SDK 或任何兼容客户端调用。

可用模型:

  • gpt-image-2 — 高质量图片生成与编辑

异步接口

如果你需要批量生成图片、不想长时间保持连接、或希望直接获取图片 URL 而非 base64 数据,可以使用 异步图片生成接口。提交任务后立即返回,通过轮询获取生成结果。


鉴权

所有请求需在 Header 中携带 API Key:

Authorization: Bearer YOUR_API_KEY

接口列表

方法 地址 说明
POST /v1/images/generations 图片生成
POST /v1/images/edits 图片编辑(需传参考图)
POST /v1/images/async/generations 异步图片生成,返回任务 ID
POST /v1/images/async/edits 异步图片编辑,返回任务 ID

图片生成

POST /v1/images/generations

请求格式为 application/json

请求参数

参数 类型 必填 说明
model string 模型编码,如 gpt-image-2
prompt string 生成提示词
n number 输出数量,默认 1
size string 输出尺寸,支持分辨率格式或 auto(默认)
quality string 画质档位:lowmediumhighauto(默认)
response_format string 响应格式:b64_json(默认)或 url

请求示例

curl -X POST https://cdn.12ai.org/v1/images/generations \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer sk_your_access_key" \
  -d '{
    "model": "gpt-image-2",
    "prompt": "一只站在城市霓虹幕墙前的机械狐狸,电影感光影,细节丰富",
    "size": "1536x1024",
    "quality": "high"
  }'

图片编辑

POST /v1/images/edits

请求格式为 multipart/form-data

请求参数

参数 类型 必填 说明
model string 模型编码,如 gpt-image-2
prompt string 编辑提示词
image file 参考图文件,支持多张
mask file 遮罩图文件,需包含 alpha 通道
n number 输出数量,默认 1
size string 输出尺寸,支持分辨率格式或 auto(默认)
quality string 画质档位:lowmediumhighauto(默认)
response_format string 响应格式:b64_json(默认)或 url

遮罩要求:遮罩图需与编辑图尺寸和格式一致(小于 50MB),且必须包含 alpha 通道。提供多张参考图时,遮罩应用于第一张图。


尺寸参数(size)

支持两种格式:

  • auto(默认):由模型自动决定最佳尺寸
  • 分辨率格式:如 1024x10241536x10242048x20483840x2160 等,支持任意自定义分辨率,只需满足下方约束条件

常用尺寸

尺寸 说明
1024x1024 正方形
1536x1024 横版
1024x1536 竖版
2048x2048 2K 正方形
2048x1152 2K 横版
3840x2160 4K 横版
2160x3840 4K 竖版
auto 默认,模型自动选择

尺寸约束

  • 最大边长 ≤ 3840px
  • 两边均须为 16px 的倍数
  • 长短边比例不超过 3:1
  • 总像素数范围:655,360 ~ 8,294,400

超过 2560x1440(约 3,686,400 像素)的输出为实验性功能。正方形图片通常生成最快。


响应格式

/v1/images/generations 和 /v1/images/edits

两个接口都支持 response_format 参数:

说明
b64_json 默认值。图片以 base64 字符串返回在 data[].b64_json 中,适合服务端自行保存或二次处理
url 图片会转存为可访问的 URL,并返回在 data[].url 中,适合前端直接展示或下载

当请求参数 n 大于 1 时,响应的 data 数组会包含多张图片。返回字段会跟随 response_format

  • response_format=b64_json:每一项返回 data[].b64_json
  • response_format=url:每一项返回 data[].url

以下为 n=1response_format=b64_json 时的响应示例:

{
  "created": 1745000000,
  "data": [
    {
      "b64_json": "/9j/4AAQSkZJRg...",
      "revised_prompt": "优化后的提示词"
    }
  ]
}

例如 n=2response_format=b64_json 时,data 中会按生成数量返回多个同结构对象:

{
  "created": 1745000000,
  "data": [
    {
      "b64_json": "/9j/4AAQSkZJRg...image_1...",
      "revised_prompt": "优化后的提示词 1"
    },
    {
      "b64_json": "/9j/4AAQSkZJRg...image_2...",
      "revised_prompt": "优化后的提示词 2"
    }
  ]
}

当请求参数 response_formaturl 时,响应中的图片会以 URL 形式返回:

{
  "created": 1745000000,
  "data": [
    {
      "url": "https://img.example.com/images/example.png",
      "revised_prompt": "优化后的提示词"
    }
  ]
}

错误响应

{
  "error": {
    "message": "错误描述"
  }
}
HTTP 状态码 说明
400 请求参数错误
401 鉴权失败
402 余额不足
403 内容安全策略拦截
429 请求频率超限
502 上游服务异常

注意事项

  • gpt-image-2 始终以高保真度处理输入图片,编辑请求的输入 token 消耗可能较高

代码示例

使用 OpenAI SDK

from openai import OpenAI
import base64
import requests

client = OpenAI(
    api_key="sk_your_access_key",
    base_url="https://cdn.12ai.org/v1",
)

# 图片生成
result = client.images.generate(
    model="gpt-image-2",
    prompt="一只赛博朋克风格的猫",
    n=2,
    size="1024x1024",
    quality="high",
    response_format="b64_json",
)

for index, item in enumerate(result.data, start=1):
    if item.b64_json:
        image_bytes = base64.b64decode(item.b64_json)
    elif item.url:
        image_resp = requests.get(item.url, timeout=120)
        image_resp.raise_for_status()
        image_bytes = image_resp.content
    else:
        continue

    with open(f"output_{index}.png", "wb") as f:
        f.write(image_bytes)

图片生成(requests)

import requests
import base64

resp = requests.post(
    "https://cdn.12ai.org/v1/images/generations",
    headers={
        "Authorization": "Bearer sk_your_access_key",
        "Content-Type": "application/json",
    },
    json={
        "model": "gpt-image-2",
        "prompt": "一只赛博朋克风格的猫",
        "n": 2,
        "size": "1536x1024",
        "quality": "high",
        "response_format": "b64_json",
    },
    timeout=600,
)

for index, item in enumerate(resp.json()["data"], start=1):
    if item.get("b64_json"):
        image_bytes = base64.b64decode(item["b64_json"])
    elif item.get("url"):
        image_resp = requests.get(item["url"], timeout=120)
        image_resp.raise_for_status()
        image_bytes = image_resp.content
    else:
        continue

    with open(f"output_{index}.png", "wb") as f:
        f.write(image_bytes)

图片编辑 — 上传本地文件(支持遮罩)

import base64
from contextlib import ExitStack
from datetime import datetime
from io import BytesIO

import requests
from PIL import Image

BASE_URL = "https://cdn.12ai.org"
API_KEY = "sk_your_access_key"

# 本地参考图路径,可按需保留一张或传多张。
REFERENCE_IMAGE_PATHS = [
    "reference_primary.png",
    "reference_secondary.png",
]

# 可选:黑白遮罩图路径。留空表示不使用遮罩。
# 黑色区域会转为透明区域,表示需要编辑;白色区域表示保留。
MASK_PATH = ""  # 例如:"edit_mask.png"

data = {
    "model": "gpt-image-2",
    "prompt": "根据参考图调整画面内容,并保持整体构图自然一致",
    "n": 2,
    "size": "1024x1024",
    "quality": "high",
    "response_format": "b64_json",  # 也可以改为 "url"
}

with ExitStack() as stack:
    files = []
    for index, image_path in enumerate(REFERENCE_IMAGE_PATHS, start=1):
        image_file = stack.enter_context(open(image_path, "rb"))
        files.append(("image", (f"reference_{index}.png", image_file, "image/png")))

    if MASK_PATH:
        mask = Image.open(MASK_PATH).convert("L")
        mask_rgba = Image.new("RGBA", mask.size, (255, 255, 255, 255))
        mask_rgba.putalpha(mask)

        mask_buffer = BytesIO()
        stack.callback(mask_buffer.close)
        mask_rgba.save(mask_buffer, format="PNG")
        mask_buffer.seek(0)
        files.append(("mask", ("mask.png", mask_buffer, "image/png")))

    resp = requests.post(
        f"{BASE_URL}/v1/images/edits",
        headers={"Authorization": f"Bearer {API_KEY}"},
        data=data,
        files=files,
        timeout=600,
    )

resp.raise_for_status()
result = resp.json()

for index, item in enumerate(result.get("data", []), start=1):
    timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
    filename = f"edited_image_{timestamp}_{index}.png"

    if item.get("b64_json"):
        image_bytes = base64.b64decode(item["b64_json"])
    elif item.get("url"):
        image_resp = requests.get(item["url"], timeout=120)
        image_resp.raise_for_status()
        image_bytes = image_resp.content
    else:
        continue

    with open(filename, "wb") as f:
        f.write(image_bytes)
    print(f"图片已保存:{filename}")