Gemini 图片接入
Gemini 原生出图使用 generateContent 内容结构:文本与参考图放在 contents[].parts[] 中,生成内容从 candidates[].content.parts[] 读取。这与 OpenAI Images 的 prompt / data 结构不同。
接入方式与鉴权
在 控制台 确认支持图片输出的模型 ID、平台路由及鉴权方式。
| 接入方式 | 调用约定 |
|---|---|
| 官方 Gemini API | POST /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://art-api.yuyuflow.com/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.jsonYOUR_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),不要只复制可见文字再当成完整历史。
平台异步封装
异步接入需要先完成提交、按任务协议等待成功,再取得最终生成内容。内容层仍按本页的 contents 和 candidates 结构处理,但不代表提交回执也是该结构。
上线前请确认任务 ID 字段、查询方法、终态、失败原因、超时策略和最终结果所在字段。不要使用视频任务路径,也不要把 streamGenerateContent 当作任务查询接口。

