Gemini 生图 API
用灵眸 Gemini 原生 v1beta 接口完成文生图、图片编辑与图生图,支持 1K / 2K / 4K、常用画幅与 Base64 图片解析。
灵眸提供 Gemini 原生 v1beta 兼容接口,可直接调用 Gemini 图片模型完成文生图、图片编辑和图生图。
接口协议
Gemini 生图使用的是 Google Gemini 原生 generateContent 协议,不是 OpenAI 的 /v1/chat/completions,也不是 OpenAI Images 的 /v1/images/generations。
主端点:
POST https://api.lmuai.com/v1beta/models/{model}:generateContent1. 接口总览
| 方法 | 路径 | 说明 |
|---|---|---|
GET | /v1beta/models | 查询当前 API Key 在 Gemini 分组下可用的原生模型 |
GET | /v1beta/models/{model} | 查询指定模型信息 |
POST | /v1beta/models/{model}:generateContent | 文生图、图片编辑、图生图主接口 |
POST | /v1beta/models/{model}:streamGenerateContent?alt=sse | 流式生成;图片场景不建议作为首选 |
GET | /v1/models | OpenAI 兼容模型列表,适合通用模型选择器 |
POST | /v1/images/batches | 灵眸 Gemini 异步批量生图扩展接口,详见Gemini 批量生图 API |
Base URL:
https://api.lmuai.com2. 鉴权
推荐:Gemini 原生请求头
x-goog-api-key: YOUR_API_KEY兼容:Bearer 请求头
Authorization: Bearer YOUR_API_KEY服务端按以下优先级读取 API Key:
x-goog-api-key;Authorization: Bearer ...;x-api-key;/v1beta路径的?key=...查询参数。
不要把 Key 放进 URL
?api_key=... 已弃用并会返回 400。?key=... 虽然兼容,但容易被浏览器历史、反向代理和访问日志记录,生产环境请使用请求头。
典型鉴权错误:
{
"error": {
"code": 401,
"message": "Invalid API key",
"status": "UNAUTHENTICATED"
}
}API Key 必须绑定到 gemini 平台分组,否则不能调用 Gemini 原生接口。
3. 模型与可用性
本次图片服务主要使用以下客户端模型 ID:
| 模型 ID | 建议用途 | 图片编辑说明 |
|---|---|---|
gemini-3.1-flash-image | 默认推荐 | 已通过生产环境 inlineData 图片编辑实测 |
gemini-3.1-flash-image-preview | 预览兼容 | 使用同一 generateContent 编辑协议,正式接入前建议单独验证 |
gemini-3-pro-image | 质量优先 / 复杂编辑 | 使用同一 generateContent 编辑协议,以当前 Key 可用性为准 |
gemini-3-pro-image-preview | Pro 预览兼容 | 使用同一编辑协议,执行模型以服务端响应为准 |
gemini-3.1-flash-lite-image | 轻量场景 | 仅在模型列表返回且已验证图片输出时使用 |
查询当前 Key 的 Gemini 模型
curl 'https://api.lmuai.com/v1beta/models' \
-H 'x-goog-api-key: YOUR_API_KEY'OpenAI 兼容模型列表:
curl 'https://api.lmuai.com/v1/models' \
-H 'Authorization: Bearer YOUR_API_KEY'模型 ID 可能经过服务端映射
客户端提交的是请求模型 ID。灵眸支持兼容模型别名,因此请求模型名称不一定等于响应中的最终模型版本。
不要仅根据模型名称猜测是否可用;请以当前 Key 调用 /v1beta/models 的实际结果为准。
4. 快速开始:文生图
curl --request POST \
'https://api.lmuai.com/v1beta/models/gemini-3.1-flash-image:generateContent' \
--header 'x-goog-api-key: YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--data-raw '{
"contents": [
{
"role": "user",
"parts": [
{
"text": "一只戴着宇航员头盔的橘猫,电影感灯光,精致细节"
}
]
}
],
"generationConfig": {
"responseModalities": ["TEXT", "IMAGE"],
"imageConfig": {
"aspectRatio": "1:1",
"imageSize": "1K"
}
}
}'成功后,从下面的位置读取图片:
candidates[].content.parts[].inlineData.data5. 文生图请求结构
{
"contents": [
{
"role": "user",
"parts": [
{
"text": "电影感雨夜城市街景,霓虹灯倒映在湿润路面,广角构图"
}
]
}
],
"generationConfig": {
"responseModalities": ["TEXT", "IMAGE"],
"imageConfig": {
"aspectRatio": "16:9",
"imageSize": "2K"
}
}
}请求字段
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
contents | array | 是 | 对话内容数组,至少包含一条用户消息 |
contents[].role | string | 建议 | 用户输入使用 user |
contents[].parts | array | 是 | 文本或输入图片片段 |
parts[].text | string | 文生图必填 | 图片提示词 |
generationConfig | object | 是 | 生成参数 |
generationConfig.responseModalities | string[] | 是 | 生图必须包含 IMAGE,推荐 ['TEXT', 'IMAGE'] |
generationConfig.imageConfig | object | 是 | 图片分辨率和画幅配置 |
图片参数必须放在 imageConfig
请使用 generationConfig.imageConfig。不要使用 responseFormat.image;该字段可能不会报参数错误,但不会按照 Gemini 原生图片参数生效。
6. 分辨率和画幅
支持的分辨率
imageSize | 推荐场景 | 特点 |
|---|---|---|
1K | 草图、快速预览、批量筛选 | 通常速度更快、费用更低 |
2K | 常规交付、文章配图、电商素材 | 质量、耗时和成本较均衡 |
4K | 精细大图、高质量交付 | 通常生成和传输时间更长 |
imageSize 必须使用大写:
{
"imageSize": "2K"
}支持的画面比例
aspectRatio 是模型级能力,不能把 Flash 的扩展比例用于 Pro 模型。灵眸会按请求模型校验比例,避免把已知无效组合发送到上游。
通用 10 种比例:
1:1
2:3
3:2
3:4
4:3
4:5
5:4
9:16
16:9
21:9Flash 扩展 4 种比例:
1:4
1:8
4:1
8:1模型比例矩阵
| 客户端模型 ID | 确认支持的比例 | 数量 |
|---|---|---|
gemini-3.1-flash-image | 通用 10 种 + Flash 扩展 4 种 | 14 |
gemini-3.1-flash-image-preview | 通用 10 种 + Flash 扩展 4 种 | 14 |
gemini-3.1-flash-lite-image | 通用 10 种 + Flash 扩展 4 种 | 14 |
gemini-3-pro-image | 仅通用 10 种 | 10 |
gemini-3-pro-image-preview | 仅通用 10 种 | 10 |
Pro 模型不支持 Flash 扩展比例
对 gemini-3-pro-image 或 gemini-3-pro-image-preview 传入 1:4、1:8、4:1、8:1 会返回 INVALID_ARGUMENT 或中转站 400 参数错误。例如:
{
"error": {
"code": 400,
"message": "generationConfig.imageConfig.aspectRatio has an unsupported value",
"status": "INVALID_ARGUMENT"
}
}上述矩阵结合 Google 官方模型说明和灵眸生产接口实测得到:三个 Flash / Flash Lite 模型均通过扩展比例测试;两个 Pro 模型均明确拒绝全部四个扩展比例。未知或新模型在完成验证前,应使用通用 10 种。
不指定 aspectRatio 时,由模型根据输入内容和默认策略决定画幅。不要传任意小数或任意 WIDTHxHEIGHT;必须使用目标模型接受的比例枚举。
示例:
{
"generationConfig": {
"responseModalities": ["TEXT", "IMAGE"],
"imageConfig": {
"aspectRatio": "9:16",
"imageSize": "4K"
}
}
}分辨率档位不是固定像素宽高
1K、2K、4K 是模型分辨率档位。图片的实际宽高由模型根据档位和画幅计算,客户端不应固定假设一定是 1024×1024、2048×2048 或 4096×4096。
7. 图片编辑 / 图生图
Gemini 支持图片编辑,只是没有类似 GPT 的独立 /v1/images/edits 端点。
文生图和图片编辑都调用:
POST /v1beta/models/{model}:generateContent两者的区别是:
| 场景 | contents[].parts[] 内容 |
|---|---|
| 文生图 | 只有文本提示词 |
| 图片编辑 / 图生图 | 文本编辑指令 + inlineData 输入图片 |
生产环境已验证
使用 gemini-3.1-flash-image,输入 JPEG 图片并通过 inlineData 提交,已成功返回:
- HTTP
200; finishReason: STOP;image/png编辑结果;- 非空
inlineData.data; usageMetadata图片模态 Token 统计。
响应可能只包含图片 part、不包含文本 part,客户端不能要求响应中必须同时存在文字。
7.1 最小图片编辑请求
{
"contents": [
{
"role": "user",
"parts": [
{
"text": "保留人物、构图和光线,把背景修改成雨夜霓虹街道"
},
{
"inlineData": {
"mimeType": "image/png",
"data": "INPUT_IMAGE_BASE64"
}
}
]
}
],
"generationConfig": {
"responseModalities": ["TEXT", "IMAGE"],
"imageConfig": {
"aspectRatio": "1:1",
"imageSize": "1K"
}
}
}7.2 输入图片字段
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
contents[].parts[].text | string | 是 | 编辑指令,应明确哪些内容需要保留、哪些内容需要修改 |
inlineData.mimeType | string | 是 | 如 image/png、image/jpeg、image/webp |
inlineData.data | string | 是 | 纯 Base64,不要带 Data URL 前缀 |
imageConfig.aspectRatio | string | 否 | 输出画幅;需要保留输入比例时填写对应比例 |
imageConfig.imageSize | string | 否 | 输出档位:1K、2K、4K,以模型能力为准 |
Base64 不要带 Data URL 前缀
正确:
/9j/4AAQSkZJRgABAQ...不要传:
data:image/jpeg;base64,/9j/4AAQSkZJRgABAQ...输入图片过大会增加上传和处理时间,并可能因网关请求体限制返回 413。
7.3 curl 完整示例
先把本地图片转换为不换行的 Base64:
IMAGE_BASE64=$(base64 < input.jpg | tr -d '\n')然后调用图片模型:
curl --request POST \
'https://api.lmuai.com/v1beta/models/gemini-3.1-flash-image:generateContent' \
--header 'x-goog-api-key: YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--data-raw "{
\"contents\": [{
\"role\": \"user\",
\"parts\": [
{
\"text\": \"保留杯子、构图、光线和背景不变,只把杯子从蓝色改成紫色,并在杯身增加三个白色星形图案,不要添加文字\"
},
{
\"inlineData\": {
\"mimeType\": \"image/jpeg\",
\"data\": \"${IMAGE_BASE64}\"
}
}
]
}],
\"generationConfig\": {
\"responseModalities\": [\"TEXT\", \"IMAGE\"],
\"imageConfig\": {
\"aspectRatio\": \"3:2\",
\"imageSize\": \"1K\"
}
}
}"7.4 Python 图片编辑示例
import base64
import requests
api_key = "YOUR_API_KEY"
model = "gemini-3.1-flash-image"
input_path = "input.jpg"
with open(input_path, "rb") as f:
image_base64 = base64.b64encode(f.read()).decode("utf-8")
payload = {
"contents": [{
"role": "user",
"parts": [
{
"text": "保留主体和构图,把背景改成雨夜霓虹街道"
},
{
"inlineData": {
"mimeType": "image/jpeg",
"data": image_base64,
}
},
],
}],
"generationConfig": {
"responseModalities": ["TEXT", "IMAGE"],
"imageConfig": {
"aspectRatio": "3:2",
"imageSize": "1K",
},
},
}
response = requests.post(
f"https://api.lmuai.com/v1beta/models/{model}:generateContent",
headers={
"x-goog-api-key": api_key,
"Content-Type": "application/json",
},
json=payload,
timeout=300,
)
response.raise_for_status()
result = response.json()
saved = False
for candidate in result.get("candidates", []):
for part in candidate.get("content", {}).get("parts", []):
inline_data = part.get("inlineData", {})
if inline_data.get("data"):
mime_type = inline_data.get("mimeType", "image/png")
extension = "jpg" if "jpeg" in mime_type else "webp" if "webp" in mime_type else "png"
with open(f"gemini-edited.{extension}", "wb") as f:
f.write(base64.b64decode(inline_data["data"]))
saved = True
break
if saved:
break
if not saved:
raise RuntimeError("HTTP 请求成功,但响应中没有编辑后的图片")7.5 编辑提示词建议
图片编辑提示词最好明确区分“保留项”和“修改项”:
保留:主体身份、姿势、镜头角度、构图和光线。
修改:把背景改成雨夜霓虹街道。
禁止:不要增加文字,不要改变人物脸部。相比只写“把它改好看一些”,这种结构更容易获得稳定结果。
7.6 多张参考图
部分 Gemini 图片模型可以在同一个 parts[] 中接收多张 inlineData 图片,用于风格参考、人物参考或素材融合。但不同模型允许的参考图数量和总请求体大小不同,正式使用前应针对当前模型单独验证。
不要仅因为 /v1beta/models 返回了某个图片模型,就假定它支持无限数量的参考图。
8. 成功响应
典型响应:
{
"candidates": [
{
"content": {
"role": "model",
"parts": [
{
"text": "已根据要求生成图片。"
},
{
"inlineData": {
"mimeType": "image/png",
"data": "BASE64_IMAGE_DATA"
}
}
]
},
"finishReason": "STOP",
"index": 0
}
],
"usageMetadata": {
"promptTokenCount": 123,
"candidatesTokenCount": 1120,
"totalTokenCount": 1450,
"candidatesTokensDetails": [
{
"modality": "IMAGE",
"tokenCount": 1024
}
]
},
"modelVersion": "MODEL_VERSION"
}关键响应字段
| 字段 | 说明 |
|---|---|
candidates[] | 候选输出列表 |
candidates[].content.parts[] | 文本或图片片段 |
parts[].inlineData.mimeType | 返回图片 MIME 类型 |
parts[].inlineData.data | 返回图片 Base64 内容 |
candidates[].finishReason | 结束原因;常见成功值为 STOP |
usageMetadata | 输入、输出及图片模态 token 统计 |
modelVersion | 上游返回的实际模型版本信息,若有则透传 |
正确判断生图成功
客户端应同时检查:
- HTTP 状态码为
2xx; candidates非空;- 至少一个
parts[]含有非空inlineData.data; - Base64 能成功解码;
- 必要时检查
finishReason。
HTTP 200 不等于一定生成了图片
上游可能返回 HTTP 200,但响应中没有 inlineData.data。这类请求必须按“业务生图失败”处理,不能计入成功图片数。
9. Node.js 示例
import { writeFile } from 'node:fs/promises';
const BASE_URL = process.env.GEMINI_BASE_URL || 'https://api.lmuai.com';
const API_KEY = process.env.GEMINI_API_KEY;
const MODEL = 'gemini-3.1-flash-image';
if (!API_KEY) throw new Error('缺少 GEMINI_API_KEY');
const payload = {
contents: [
{
role: 'user',
parts: [
{ text: '日落时分的海边灯塔,水彩插画,温暖色调,细腻纸张纹理' },
],
},
],
generationConfig: {
responseModalities: ['TEXT', 'IMAGE'],
imageConfig: {
aspectRatio: '16:9',
imageSize: '2K',
},
},
};
const controller = new AbortController();
const timer = setTimeout(() => controller.abort(), 300_000);
try {
const response = await fetch(
`${BASE_URL}/v1beta/models/${encodeURIComponent(MODEL)}:generateContent`,
{
method: 'POST',
headers: {
'x-goog-api-key': API_KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify(payload),
signal: controller.signal,
},
);
const text = await response.text();
let data;
try {
data = JSON.parse(text);
} catch {
throw new Error(`服务返回非 JSON 内容:HTTP ${response.status}`);
}
if (!response.ok) {
throw new Error(
`HTTP ${response.status}: ${data?.error?.message || JSON.stringify(data)}`,
);
}
const parts = data.candidates?.flatMap((candidate) => candidate.content?.parts || []) || [];
const imagePart = parts.find((part) => part.inlineData?.data);
if (!imagePart) {
const reasons = data.candidates?.map((candidate) => candidate.finishReason).filter(Boolean);
throw new Error(`请求完成但没有图片,finishReason=${reasons?.join(',') || 'unknown'}`);
}
const mimeType = imagePart.inlineData.mimeType || 'image/png';
const extension = mimeType === 'image/jpeg'
? 'jpg'
: mimeType === 'image/webp'
? 'webp'
: 'png';
await writeFile(
`gemini-output.${extension}`,
Buffer.from(imagePart.inlineData.data, 'base64'),
);
console.log('图片已保存,usageMetadata:', data.usageMetadata || null);
} finally {
clearTimeout(timer);
}10. Python 示例
import base64
import os
from pathlib import Path
import requests
BASE_URL = os.getenv("GEMINI_BASE_URL", "https://api.lmuai.com")
API_KEY = os.environ["GEMINI_API_KEY"]
MODEL = "gemini-3.1-flash-image"
payload = {
"contents": [
{
"role": "user",
"parts": [
{"text": "未来主义建筑群,清晨薄雾,超广角摄影,真实材质"}
],
}
],
"generationConfig": {
"responseModalities": ["TEXT", "IMAGE"],
"imageConfig": {
"aspectRatio": "16:9",
"imageSize": "2K",
},
},
}
response = requests.post(
f"{BASE_URL}/v1beta/models/{MODEL}:generateContent",
headers={
"x-goog-api-key": API_KEY,
"Content-Type": "application/json",
},
json=payload,
timeout=300,
)
data = response.json()
if not response.ok:
message = data.get("error", {}).get("message", data)
raise RuntimeError(f"HTTP {response.status_code}: {message}")
image_part = None
for candidate in data.get("candidates", []):
for part in candidate.get("content", {}).get("parts", []):
if part.get("inlineData", {}).get("data"):
image_part = part
break
if image_part:
break
if not image_part:
reasons = [candidate.get("finishReason") for candidate in data.get("candidates", [])]
raise RuntimeError(f"请求完成但没有返回图片,finishReason={reasons}")
inline_data = image_part["inlineData"]
mime_type = inline_data.get("mimeType", "image/png")
extension = {
"image/jpeg": "jpg",
"image/webp": "webp",
}.get(mime_type, "png")
Path(f"gemini-output.{extension}").write_bytes(
base64.b64decode(inline_data["data"])
)
print("图片已保存")
print("usageMetadata:", data.get("usageMetadata"))11. 常见错误
Gemini 原生端点通常返回 Google 风格错误:
{
"error": {
"code": 429,
"message": "upstream rate limit exceeded",
"status": "RESOURCE_EXHAUSTED"
}
}| HTTP 状态 | 常见原因 | 建议 |
|---|---|---|
400 | 请求结构、模型路径或分组平台错误 | 修正请求,不要直接重试 |
401 | API Key 缺失、无效或禁用 | 检查 Key 和请求头 |
402 / 403 | 余额、订阅、计费资格或权限不足 | 检查账户和分组权限 |
413 | 图生图请求体过大 | 压缩输入图片 |
429 | 用户并发限制或上游限流 | 指数退避,降低并发和 RPM |
500 | 内部或容量错误 | 记录错误码和请求 ID,有限重试 |
502 | 上游认证、权限或服务暂时失败 | 退避重试,必要时联系管理员 |
503 | 无可用 Gemini 账号或上游过载 | 延迟重试并降低流量 |
504 | 网关或上游超时 | 作为独立请求重新发起 |
如果错误信息提示所有 Token 均处于禁用、冷却、锁定或过期状态,属于服务容量问题,不是提示词格式错误。请停止密集重试,并将错误码和请求 ID 提供给管理员。
12. 超时、重试和并发
客户端超时建议
| 分辨率 | 建议总超时 |
|---|---|
1K | 不低于 120 秒 |
2K | 不低于 180 秒 |
4K | 建议 300 秒 |
这只是接入建议,不代表固定 SLA。若请求还经过自有 Nginx、CDN 或 API 网关,需要同步调整这些组件的读取超时。
重试建议
建议重试:
429;502、503、504;- 网络中断、连接重置和读取超时;
- HTTP
200但没有图片时,可有限重试一次并保存原始响应。
通常不要重试:
400;401;- 明确的余额或权限错误;
- 请求参数或内容策略错误。
推荐最多重试 2~3 次,并使用指数退避:
第 1 次:1~2 秒随机抖动
第 2 次:3~5 秒随机抖动
第 3 次:8~12 秒随机抖动多张实时图片
实时接口当前按“一次请求一张主要图片”使用。需要多张时应拆成多个独立请求,并同时限制:
- 最大在途并发;
- 每分钟请求数(RPM);
- 单用户任务数;
- 超时与最大重试次数。
如果需要提交几十到数百条提示词并异步等待结果,请使用Gemini 批量生图 API。
13. 用量与计费
响应中的 usageMetadata 可用于分析输入、输出和图片模态 token,但不一定等于最终扣费金额。
实际扣费可能受以下因素影响:
- 请求模型 ID 与实际映射模型;
1K、2K、4K图片档位;- 分组图片单价;
- 用户分组倍率和上游账户倍率;
- 部署环境中的计费规则。
最终金额请以灵眸控制台的用量明细和账户余额变化为准。
进行质量或并发测试时,建议记录:
- 测试前余额;
- 测试后余额;
- 成功请求数;
- 实际返回图片数;
- 模型、分辨率和画幅;
- 余额差额;
- 单张成功图片平均成本。
用量记录可能异步落账,测试结束后可等待一段时间再核对最终金额。
14. 安全建议
- API Key 只保存在服务端环境变量或密钥管理系统;
- 不要在浏览器前端、移动端安装包或公开代码仓库中写入 Key;
- 日志不要打印完整 API Key 和完整图片 Base64;
- 校验输入图片 MIME 类型、文件大小和 Base64 合法性;
- 保存响应时根据
inlineData.mimeType选择扩展名; - 为每个业务请求记录自己的 trace ID、请求时间、模型、分辨率和 HTTP 状态;
- 超时后不要在极短时间内重复创建大量相同请求。
15. 接入验收清单
- 能使用
/v1beta/models获取当前 Key 的 Gemini 模型列表; - 能使用
x-goog-api-key或 Bearer 请求头鉴权; - 能完成一张
1K / 1:1文生图; - 能完成
2K和4K文生图; - 能完成至少一次图片编辑 / 图生图;
- 能识别
inlineData.mimeType和inlineData.data; - 能把 HTTP 200 但没有图片的情况标记为失败;
- 已设置图片请求超时;
- 已对 429 和 5xx 实现有限次数指数退避;
- 已确认价格、余额、并发和 RPM;
- 日志不会泄露 API Key 或完整 Base64。
下一步
- 大量提示词异步生成:Gemini 批量生图 API
- 查询当前 Key 可用模型:模型广场
- 协议和 Base URL 说明:接入协议
- 查询请求用量:导出 Usage 使用明细
最后更新:
开通灵眸 API,立即用上 Claude / Codex 等主流 AI 工具
零门槛注册、套餐灵活、国内直连。支持 Claude Code、Codex CLI、Cursor、VS Code 插件、OpenCode、Cherry Studio 等工具接入。
前往注册