跳到正文

生图接入指南 ​

适合需要通过 API 或 SDK 生成、编辑图片的用户。选一条协议路径,生成或编辑一张图片,保存后再核对使用记录。

先看结论 ​

模型请求地址认证头图片通常在哪里
gpt-image-2生成:https://api.bestai.chat/v1/images/generations
编辑:https://api.bestai.chat/v1/images/edits
Authorization: Bearer <BestAI Key>data[].b64_json,有些上游也会返回 data[].url
gemini-3.1-flash-imagehttps://api.bestai.chat/v1beta/models/gemini-3.1-flash-image:generateContentx-goog-api-key: <BestAI Key>candidates[].content.parts[].inlineData
gemini-3-pro-image同上,把 URL 中的模型名替换掉x-goog-api-key: <BestAI Key>candidates[].content.parts[].inlineData

几点需要先分清:

  • 这里的 <BestAI Key> 是你在 BestAI 控制台创建的 Key,不是 Google AI Studio Key,也不是 OpenAI 官方 Key。
  • OpenAI 生成和编辑使用两个 endpoint;Gemini 没有单独的编辑 endpoint,在同一个 generateContent 请求中附上原图即可。
  • 模型、分组、尺寸和价格属于运营配置,以控制台当前显示为准。文档中的模型名只用于示例。
  • gemini-3-pro-image 和 gemini-3.1-flash-image 是两种模型 ID。BestAI 的可用性和上游映射由当前分组决定,不凭模型名推断路由或能力。
  • 下面的验证请求会产生用量。OpenAI 示例用 1024x1024 和 n=1;Gemini 示例用 imageSize="1K",不使用 n 字段。输出规格不代表固定价格。

开始前准备 ​

在当前终端设置 Key。不要把真实值写进代码仓库、截图或聊天记录:

bash
export BESTAI_API_KEY="sk-你的Key"

建议先在仪表盘确认余额和 Key 额度,再开始测试。

以下 curl 和 heredoc 命令适用于 Bash / Zsh / WSL,保存脚本需要 Python 3。Windows PowerShell 用户可选用 OpenAI Python SDK 示例;Bash 的 <<'PY' 语法不能直接用于 PowerShell。每次只执行选中的生成或编辑路径,不必逐条运行全文。

curl -sS 收到 HTTP 错误时也可能正常退出。先确认输出的 HTTP 状态,再解析保存的 JSON;失败后先读错误,不直接重试生成。示例响应文件会被同名的新响应覆盖,重跑前保留需要的旧 JSON。

OpenAI:gpt-image-2 ​

1. 发出最小请求 ​

OpenAI 图片接口的 Base URL 是 https://api.bestai.chat/v1,完整 endpoint 是 /images/generations。请求体先只保留模型、提示词、尺寸和数量:

bash
curl -sS \
  "https://api.bestai.chat/v1/images/generations" \
  -H "Authorization: Bearer $BESTAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-image-2",
    "prompt": "一张简洁的蓝色几何海报,纯色背景,居中构图",
    "size": "1024x1024",
    "n": 1
  }' \
  -o openai-image-response.json \
  -w "HTTP %{http_code}\n"

注意:这里把响应保存成 JSON 文件。不要把整个 JSON 直接重命名成 .png,图片数据还需要解码。

2. 读取并保存图片 ​

OpenAI 返回的常见结构是 data[0].b64_json。部分兼容上游会返回 data[0].url,下面脚本也支持下载。脚本只使用 Python 标准库;第二个参数指定输出文件前缀,已有图片不会被覆盖:

bash
python3 - openai-image-response.json bestai-image <<'PY'
import base64
import json
import sys
import urllib.request
import urllib.parse

with open(sys.argv[1], encoding="utf-8") as f:
    response = json.load(f)

if response.get("error"):
    raise SystemExit(response["error"])

item = (response.get("data") or [None])[0]
if not item:
    raise SystemExit("响应中没有 data[0]")

if item.get("b64_json"):
    image = base64.b64decode(item["b64_json"], validate=True)
elif item.get("url"):
    # URL 可能有有效期,拿到后立即下载,不要把完整 URL 写入日志。
    if urllib.parse.urlsplit(item["url"]).scheme not in ("https", "http"):
        raise SystemExit("图片 URL 必须是 HTTP 或 HTTPS 地址")
    with urllib.request.urlopen(item["url"], timeout=120) as source:
        image = source.read()
else:
    raise SystemExit("data[0] 中没有 b64_json 或 url")

if image.startswith(b"\x89PNG\r\n\x1a\n"):
    suffix = ".png"
elif image.startswith(b"\xff\xd8"):
    suffix = ".jpg"
elif image.startswith(b"RIFF") and image[8:12] == b"WEBP":
    suffix = ".webp"
else:
    raise SystemExit("返回内容不是可识别的 PNG、JPEG 或 WebP,请检查响应")

output = sys.argv[2] + suffix
with open(output, "xb") as f:
    f.write(image)
print(f"已保存 {output} ({len(image)} bytes)")
PY

出现 FileExistsError 时换一个输出前缀,不要删除尚需保留的图片。脚本识别实际格式后选择后缀;仍应使用图片查看器打开确认文件完整。

3. 使用原图编辑图片 ​

编辑接口是 POST /v1/images/edits。这里使用 multipart/form-data 上传本地原图,先准备一张 PNG、JPEG 或 WebP 图片:

bash
export SOURCE_IMAGE="./source.png"

curl -sS \
  "https://api.bestai.chat/v1/images/edits" \
  -H "Authorization: Bearer $BESTAI_API_KEY" \
  -F "image=@${SOURCE_IMAGE}" \
  -F "model=gpt-image-2" \
  -F "prompt=保留主体和构图,只把白色背景改为浅蓝色" \
  -F "size=1024x1024" \
  -F "n=1" \
  -o openai-image-edit-response.json \
  -w "HTTP %{http_code}\n"

curl -F 会自动生成包含 boundary 的 Content-Type,不要手动填写该请求头。首次使用较小的原图,按不超过 20 MiB(20 × 1024 × 1024 字节)的单文件大小准备;站点总请求大小和所选上游可能有更低限制。

编辑响应与生成响应的取图方式相同。复用上面脚本,将输入文件名改为 openai-image-edit-response.json,输出前缀改为 bestai-image-edit。

4. OpenAI SDK 的最小写法 ​

在自己的 Python 环境先运行 python -m pip install openai。下例保存为 .py,用同一环境运行,读取已设置的 BESTAI_API_KEY。SDK 响应先存成 JSON,再复用前面的取图脚本;不把未知格式的数据直接命名为 PNG:

python
import os
from pathlib import Path
from openai import OpenAI

client = OpenAI(
    base_url="https://api.bestai.chat/v1",
    api_key=os.environ["BESTAI_API_KEY"],
)

output_path = Path("openai-image-response.json")
if output_path.exists():
    raise SystemExit("响应文件已存在,请先更换 output_path 再调用")

result = client.images.generate(
    model="gpt-image-2",
    prompt="一张简洁的蓝色几何海报,纯色背景,居中构图",
    size="1024x1024",
    n=1,
)

with output_path.open("x", encoding="utf-8") as output:
    output.write(result.model_dump_json())
print("已保存 openai-image-response.json,请继续执行取图脚本")

要编辑时,保留上面的 import 与 client 初始化,用下面代码替换生成调用及保存步骤,不需要先生成一张新图:

python
output_path = Path("openai-image-edit-response.json")
if output_path.exists():
    raise SystemExit("响应文件已存在,请先更换 output_path 再调用")

with open("source.png", "rb") as source:
    result = client.images.edit(
        model="gpt-image-2",
        image=source,
        prompt="保留主体和构图,只把白色背景改为浅蓝色",
        size="1024x1024",
        n=1,
    )
with output_path.open("x", encoding="utf-8") as output:
    output.write(result.model_dump_json())
print("已保存 openai-image-edit-response.json,请继续执行取图脚本")

SDK 示例也使用不覆盖模式保存 JSON;再次调用前换一个文件名。PowerShell 下取图时,将前面两个 PY 标记之间的 Python 代码保存为 save_openai_image.py,运行 python save_openai_image.py openai-image-response.json bestai-image。

某些客户端会把 gpt-image-2 作为 Responses API 的 image_generation 工具调用。那是另一条协议路径;本文的最小验证使用 Images API。如果客户端报“不支持 /v1/responses”,请在客户端切换到图片接口,或按该客户端的 Responses 配置说明处理。

Gemini:gemini-3.1-flash-image ​

1. 发出原生 Gemini 请求 ​

Gemini 原生兼容接口的 Base URL 是 https://api.bestai.chat/v1beta。generateContent 是 endpoint 的动作名,不能省略:

bash
export GEMINI_IMAGE_MODEL="gemini-3.1-flash-image"

curl -sS \
  "https://api.bestai.chat/v1beta/models/${GEMINI_IMAGE_MODEL}:generateContent" \
  -H "x-goog-api-key: $BESTAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "contents": [
      {
        "role": "user",
        "parts": [
          {"text": "生成一个简单的绿色圆形,纯色背景,仅用于接口验证"}
        ]
      }
    ],
    "generationConfig": {
      "responseModalities": ["TEXT", "IMAGE"],
      "imageConfig": {
        "aspectRatio": "1:1",
        "imageSize": "1K"
      }
    }
  }' \
  -o gemini-image-response.json \
  -w "HTTP %{http_code}\n"

本例用 responseModalities: ["TEXT", "IMAGE"] 请求文本和图片,不将模态限制为只有 TEXT。aspectRatio 和 imageSize 是生成配置,不要放在 contents 里。常见比例包括 1:1、16:9、9:16、4:3 和 3:4;1K、2K、4K 是否可用,以当前模型和分组为准。

2. 从 inlineData 保存图片 ​

Gemini 的图片通常位于 candidates[].content.parts[] 中,字段名是大小写敏感的 inlineData,其中:

  • mimeType 是图片类型,例如 image/png 或 image/jpeg。
  • data 是不带 data:image/...;base64, 前缀的 Base64 字符串。

下面脚本保存最终响应中的图片 part,跳过标记为思考过程的内容。第二个参数是输出前缀,文件已存在时会停止:

bash
python3 - gemini-image-response.json bestai-gemini <<'PY'
import base64
import json
import sys

with open(sys.argv[1], encoding="utf-8") as f:
    response = json.load(f)

if response.get("error"):
    raise SystemExit(response["error"])

count = 0
for candidate in response.get("candidates", []):
    for part in (candidate.get("content") or {}).get("parts", []):
        if part.get("thought"):
            continue
        inline = part.get("inlineData") or part.get("inline_data")
        if not inline or not inline.get("data"):
            continue

        mime = inline.get("mimeType") or inline.get("mime_type") or ""
        if not mime.startswith("image/"):
            continue
        raw = base64.b64decode(inline["data"], validate=True)
        if raw.startswith(b"\x89PNG\r\n\x1a\n"):
            suffix = ".png"
        elif raw.startswith(b"\xff\xd8"):
            suffix = ".jpg"
        elif raw.startswith(b"RIFF") and raw[8:12] == b"WEBP":
            suffix = ".webp"
        else:
            raise SystemExit("图片 part 不是可识别的 PNG、JPEG 或 WebP")
        count += 1
        output = f"{sys.argv[2]}-{count:02d}{suffix}"
        with open(output, "xb") as f:
            f.write(raw)
        print(f"已保存 {output} ({len(raw)} bytes)")

if count == 0:
    raise SystemExit("响应中没有 inlineData 图片 part")
PY

3. 使用原图编辑图片 ​

Gemini 编辑仍请求 generateContent。区别是 parts 中必须同时包含修改要求和原图 inlineData。下面的 Python 只使用标准库,用来构造请求 JSON:

bash
export SOURCE_IMAGE="./source.png"

python3 - "$SOURCE_IMAGE" > gemini-image-edit-request.json <<'PY'
import base64
import json
import pathlib
import sys

source = pathlib.Path(sys.argv[1]).read_bytes()
if source.startswith(b"\x89PNG\r\n\x1a\n"):
    mime_type = "image/png"
elif source.startswith(b"\xff\xd8"):
    mime_type = "image/jpeg"
elif source.startswith(b"RIFF") and source[8:12] == b"WEBP":
    mime_type = "image/webp"
else:
    raise SystemExit("原图应为 PNG、JPEG 或 WebP")
request = {
    "contents": [
        {
            "role": "user",
            "parts": [
                {"text": "保留主体和构图,只把白色背景改为浅蓝色"},
                {
                    "inlineData": {
                        "mimeType": mime_type,
                        "data": base64.b64encode(source).decode("ascii"),
                    }
                },
            ],
        }
    ],
    "generationConfig": {
        "responseModalities": ["TEXT", "IMAGE"],
        "imageConfig": {"aspectRatio": "1:1", "imageSize": "1K"},
    },
}
json.dump(request, sys.stdout, ensure_ascii=False)
PY

确认生成 JSON 的步骤没有报错后,再发送请求;GEMINI_IMAGE_MODEL 使用本节前面设置的模型:

bash
curl -sS \
  "https://api.bestai.chat/v1beta/models/${GEMINI_IMAGE_MODEL}:generateContent" \
  -H "x-goog-api-key: $BESTAI_API_KEY" \
  -H "Content-Type: application/json" \
  --data-binary @gemini-image-edit-request.json \
  -o gemini-image-edit-response.json \
  -w "HTTP %{http_code}\n"

脚本按原图内容识别 MIME 类型。复用“从 inlineData 保存图片”的脚本,将输入文件名改为 gemini-image-edit-response.json,第二个参数改为 bestai-gemini-edit。重跑时换一个输出前缀,避免与旧图片重名。

4. 使用 gemini-3-pro-image ​

只需要替换模型 ID:

bash
export GEMINI_IMAGE_MODEL="gemini-3-pro-image"

请求体和保存方式不变,但要先确认 Key 的分组确实提供这个模型。模型不可用、余额不足和上游拒绝是不同问题,按错误正文分别检查,不通过反复换模型重试来处理额度问题。

批量生成多张图片 ​

如果你要处理多条提示词,或希望集中查看、下载批量任务结果,可以直接使用 BestAI 批量生图。页面已包含 Key、模型、提示词和结果下载的操作说明,不需要手工组装 API 请求。

批量生图只会显示已开通该能力的 Key 和模型,以页面实际可选内容为准。单张生成或图片编辑继续使用本文上面的 API 方式。

如何判断图片真的生成成功 ​

一次图片生成或编辑验证同时满足下面三点,才算接入完成:

  1. HTTP 请求成功,并且响应中确实找到 b64_json、url 或 inlineData 图片数据。
  2. 脚本能把图片写入本地,且文件能被图片查看器打开。
  3. 在使用记录中找到同一时间的请求,核对模型、状态和实际扣费。

只有 HTTP 200、但没有图片字段时,不要直接把响应当成图片;先保存 JSON 并检查是否返回了文本、错误或安全拦截信息。图片 URL 可能有有效期,拿到后立即下载;Base64 图片很大时也不要把完整响应打印到终端日志。

常见错误 ​

现象第一检查项
401 / 403Key 是否完整、认证头是否正确、Key 所属分组是否开放生图、余额和额度是否足够
404对照本文完整请求地址,确认没有重复路径,Gemini 没漏 /v1beta/models/ 或 :generateContent
模型不存在 / 不在白名单使用控制台当前显示的模型 ID;不要把其他分组的模型名直接照抄过来
余额不足相关错误先查自己的账户、订阅和 Key 额度;均正常时提供脱敏错误正文排查上游,不能只凭一句错误确定是哪一层余额不足
image file is requiredOpenAI 编辑请求是否使用 -F "image=@...",并确认文件存在
image_endpoint_required核对客户端是否把图片模型发到了文字接口;切到本文对应的图片协议,仍失败时保留完整错误代码排查分组能力
返回成功但没有图片检查 data[].b64_json、data[].url 或 Gemini 的 inlineData,并确认请求包含图片模态
有图片但没有使用记录先刷新并检查日期、Key 和模型筛选,再核对客户端 Base URL 和 Key

生图请求通常比短文本验证更贵。排查时保留请求时间、模型 ID、HTTP 状态和使用记录即可,不要提交完整 API Key、Cookie 或完整响应内容。

返回通用 SDK 接入指南查看其他协议,或回到文档中心选择下一项任务。

协议依据 ​

核对日期:2026-10-03。参考 OpenAI 图片接口说明、GPT Image 2 模型页及 Gemini generateContent 生图说明。

本文使用 BestAI 的 Images / generateContent 兼容路径。Google 当前示例中的 responseFormat.image 与本页的 generationConfig.imageConfig 不是同一字段;本页沿用 BestAI 已有的 imageConfig 配置,不直接混用。上游官方能力不等同于每个 BestAI 分组都已开通。

模型、协议与价格以当前分组和使用记录为准。