Skip to content

Gemini 图片接入​

Gemini 原生出图使用 generateContent 内容结构:文本与参考图放在 contents[].parts[] 中,生成内容从 candidates[].content.parts[] 读取。这与 OpenAI Images 的 prompt / data 结构不同。

接入方式与鉴权​

在 控制台 确认支持图片输出的模型 ID、平台路由及鉴权方式。

接入方式调用约定
官方 Gemini APIPOST /v1beta/models/YOUR_IMAGE_MODEL:generateContent,官方 API Key 使用 x-goog-api-key
平台原生兼容路由仅当渠道明确开放同一路径和鉴权时,才能使用下方兼容示例;平台 Key 不等于 Google Key
平台异步封装内容输入与最终生成内容沿用官方结构;提交路由、鉴权、任务回执和查询方式使用平台单独提供的协议

不要把官方鉴权或路径当作封装接口约定

下方 cURL 仅适用于已确认提供 Gemini 原生路径及 x-goog-api-key 鉴权的渠道。如果开通的是 Bearer 鉴权或异步封装,请按渠道说明替换路径与请求头;不要同时发送多种密钥头进行试探。尚未获得任务协议时,先取得平台调用说明,不要猜测查询地址或任务字段。

文本生成图片​

以下为原生兼容渠道的最小请求模板。模型放在 URL 中,不是 JSON 顶层的 model:

bash
curl --fail-with-body -X POST \
  "https://api.yu-yu.ai/v1beta/models/YOUR_IMAGE_MODEL:generateContent" \
  -H "x-goog-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "contents": [{
      "role": "user",
      "parts": [{"text": "生成一张极简咖啡店海报,暖色自然光"}]
    }],
    "generationConfig": {
      "responseModalities": ["TEXT", "IMAGE"]
    }
  }' --output response.json

YOUR_IMAGE_MODEL 必须替换成已开通且支持图片输出的模型;普通文本模型不能仅靠设置 responseModalities 变成出图模型。

请求字段​

字段说明
model(URL 路径参数)保留路径中的模型参数,将 YOUR_IMAGE_MODEL 替换为已开通模型 ID;原生请求体不额外添加此字段
contents对话内容数组
contents[].role用户输入使用 user
contents[].parts[].text文本提示词
contents[].parts[].inlineData内嵌参考图,包含 MIME 类型和 Base64
generationConfig.responseModalities请求输出模态,例如 TEXT 与 IMAGE;以模型支持为准
generationConfig.imageConfig可选图片配置;宽高比、输出尺寸等取值必须与选定模型及渠道匹配

使用参考图编辑​

将请求中的 parts 替换为下面的内容,在独立 part 中提供图片和文本:

json
[
  {
    "inlineData": {
      "mimeType": "image/png",
      "data": "BASE64_OF_INPUT_PNG"
    }
  },
  {"text": "保留杯子的外形与位置,将背景改成木质咖啡桌"}
]

data 使用图片文件的纯 Base64,不附加 data:image/png;base64, 前缀;mimeType 应与文件真实格式一致。图片数量、体积和可用格式以当前模型及渠道限制为准。不要把 OpenAI 的 image、mask 字段直接搬到 Gemini 请求体。

读取文字与图片​

最终生成内容的结构示意(字段可能按结果缺省):

json
{
  "candidates": [{
    "content": {
      "role": "model",
      "parts": [
        {"text": "已生成海报。"},
        {"inlineData": {"mimeType": "image/png", "data": "BASE64_IMAGE_DATA"}}
      ]
    }
  }]
}

不要假设第一个 part 一定是图片,也不要只读取文本。对于原生同步结果,或已从异步封装中取出的最终 GenerateContentResponse,可以使用以下代码:

python
import base64
import json
from pathlib import Path

result = json.loads(Path("response.json").read_text(encoding="utf-8"))
if result.get("error"):
    raise RuntimeError("请求失败,请检查服务端错误信息")
extensions = {"image/png": ".png", "image/jpeg": ".jpg", "image/webp": ".webp"}
count = 0
for candidate in result.get("candidates") or []:
    for part in (candidate.get("content") or {}).get("parts") or []:
        if part.get("thought"):
            continue
        if part.get("text"):
            print(part["text"])
        image = part.get("inlineData") or {}
        if not image.get("data"):
            continue
        extension = extensions.get(image.get("mimeType"))
        if not extension:
            raise RuntimeError("未知图片 MIME 类型,请先确认输出格式")
        Path(f"output-{count}{extension}").write_bytes(
            base64.b64decode(image["data"], validate=True)
        )
        count += 1
if count == 0:
    raise RuntimeError("未返回图片,请检查模型、promptFeedback 和候选 finishReason")

多轮编辑时保留原始对话 part 及服务端返回的签名字段(如 thoughtSignature),不要只复制可见文字再当成完整历史。

通过 OpenAI 图片接口调用​

Gemini 渠道上的原生出图模型(nano-banana 系列、gemini-*-image)也可以按 OpenAI Images 契约调用:下游发 POST /v1/images/generations,网关把它翻译成上面的 generateContent 结构,再按 data[].b64_json 返回图片。

OpenAI Images 字段下发位置
promptcontents[].parts[].text
size = 16:9 这类比例,或 1024x1024 / 1792x1024 这类像素写法;aspect_ratiogenerationConfig.imageConfig.aspectRatio
size = 1K / 2K / 4K / 512px(大小写不敏感);quality = hd / high → 2K,4K → 4K,其它非空值 → 1KgenerationConfig.imageConfig.imageSize(仅对确认接受该字段的模型族下发,见下)
n > 1generationConfig.candidateCount
image_size(显式传)generationConfig.imageConfig.imageSize,覆盖上面的按族判定
stream不下发:原生出图是一次性调用,请求按非流式处理

imageSize 是 3 代才引入的参数,而且各代接受的取值不同:gemini-2.5-flash-image 会以 403 拒绝 imageSize(只能用 aspect_ratio),gemini-3-pro-image* 只接受 1K / 2K / 4K(不含 512px),gemini-3.1-flash-image* 额外接受 512px;聚合上游改名的模型(gemini-nano-banana-2.1 之类)无法判断代数。因此网关只对确认接受该取值的模型下发 imageSize,其余模型只下发画面比例,分辨率取模型默认值;确实要指定分辨率时显式传 image_size(1K / 2K / 4K / 512px)。

模型名必须满足下列之一,网关才认这是原生出图模型:在「模型设置 → Gemini → 支持生图的模型」里登记(图片入口既接受完整模型名,也接受族名片段),或者同时满足「属于内置的图片模型」与「名字带 gemini / nano-banana 族名标记」(gemini-2.5-flash-image、gemini-nano-banana-2.1、nano-banana-pro-preview 等)。后者是代码级判定,不依赖实例里保存过的旧配置。

判定前会先归一模型名:去掉厂商/路径前缀(google/gemini-3-pro-image、models/gemini-2.5-flash-image,只影响判定与 URL 后缀选择,URL 里的模型名保持上游写法),并抹平 preview 后缀差异(gemini-3-pro-image ↔ gemini-3-pro-image-preview)。同一个 Imagen/Gemini 图片模型的不同上游写法因此都能命中;归一后仍按整名比较,不做族名片段匹配——配置项在对话链路(决定是否为一次对话注入 IMAGE 模态)上也只做整名匹配,把它写成 gemini、flash 这类短片段会让该渠道的纯文本模型也被要求输出图片。模型还需要在「模型倍率/定价」里配置价格,否则按次计费的生图请求会在调用上游之前失败。

厂商前缀是聚合上游的命名约定(请求路径需要原样带上)。走官方端点的 Vertex 渠道请把模型名配成裸名:Vertex 的 URL 会自行补上 publishers/google/models/,再带一层厂商前缀会拼出 publishers/google/models/google/... 而拿到上游 404;同理,倍率表按调用方传入的模型名(OriginModelName)查表,前缀名不会被 gemini-3-pro-image* 这类默认倍率命中,需要在「模型倍率」里为该名字显式配置。

/v1/images/edits(参考图 / 蒙版)暂不支持:这些模型只有 :generateContent 一个入口,丢掉参考图会生成一张与请求无关的图片,因此网关直接返回错误,请改用上面的原生结构传 inlineData。开启请求体直通(PassThroughRequestEnabled 或渠道级直通)时这个本地闸门不生效,请求体会按原样发给 :generateContent。

平台异步封装​

异步接入需要先完成提交、按任务协议等待成功,再取得最终生成内容。内容层仍按本页的 contents 和 candidates 结构处理,但不代表提交回执也是该结构。

上线前请确认任务 ID 字段、查询方法、终态、失败原因、超时策略和最终结果所在字段。不要使用视频任务路径,也不要把 streamGenerateContent 当作任务查询接口。

参考与继续阅读​