跳到正文
OpenRouter:Announcements(RSS)
精选
64AI 编辑部评分,满分 100

OpenRouter 教程:用代码调用 Nano Banana 2 编辑图像

2026-09-09 08:00· 2天前
AI 导读

OpenRouter 发布教程,演示通过 API 向 google/gemini-3.1-flash-image(即 Nano Banana 2)发送源图和文本指令完成图像编辑,编辑结果以 base64 形式在响应中返回。教程给出 Python 和 TypeScript 示例、提示词写法、多轮小步编辑方法,以及更换模型只需改一个字段,并介绍了 Nano Banana 系列四个成员的价格与质量差异。

推荐理由

原文给出完整可运行的图像编辑请求代码和提示词写法,读者可以照搬并把模型换成其他供应商做对比。

正文 · AI 翻译
Nano Banana API: Edit Images with Gemini in Code

本指南展示如何在代码中通过文本提示词编辑图像。你通过 OpenRouter API 将源图像和编辑提示词发送给 google/gemini-3.1-flash-image,编辑后的图像会在响应中返回。"Nano Banana" 是 Google Gemini 图像模型的昵称。此 slug 为 Nano Banana 2,是该系列中默认的快速模型。由于你通过 一个 API 访问它,之后只需更改一个字段即可使用不同的编辑模型。

图像编辑是对现有图像进行修改。图像生成是根据文本创建新图像。本指南涵盖的是编辑,因此这里的每个请求都包含一张源图像。如需根据文本创建图像,请参阅 图像生成文档图像生成教程

Before-and-after example of a natural-language image edit: a portrait photo, the prompt "Add a red wool scarf around the person's neck. Keep everything else the same.", and the edited result with the scarf added and everything else intact

简而言之

  • 编辑只需一次请求。将源图像放入 input_references,将指令放入 prompt,然后从 data[0].b64_json 读取编辑后的图像并将其解码到磁盘。
  • google/gemini-3.1-flash-image 是 Nano Banana 2,默认的快速 Gemini 图像模型。在使用某个模型之前,请确认它接受图像输入,因为编辑支持情况各不相同。
  • 对于本地或私有文件,将输入作为 base64 数据 URL 发送;对于托管图像,则使用普通的 HTTP(S) URL。
  • 以小步进行编辑。将每次返回的图像作为下一次的源图像发回,每次调用只给一条指令,这样修改就会逐步叠加。
  • 只需编辑一个字段即可更改编辑模型。

前置条件

你需要三样东西:

  1. 一个来自密钥页面的 OpenRouter API key,以及基础 URL https://openrouter.ai/api/v1
  2. 一个 HTTP 客户端。示例使用 Python requests 和 TypeScript fetch。你也可以使用 curl 或 OpenRouter SDK。任何能发送带 Authorization 头的 JSON POST 请求的客户端都可以。
  3. 一张源图像,可以是本地文件或公开 URL。

使用哪个模型

本指南的默认模型是 google/gemini-3.1-flash-image,即 Nano Banana 2。它以图像作为输入并返回编辑后的图像。Nano Banana 系列目前有四个成员:Nano Banana 2(google/gemini-3.1-flash-image)是本指南的默认模型,Nano Banana 2 Lite(google/gemini-3.1-flash-lite-image)最便宜、最快,Nano Banana Pro(google/gemini-3-pro-image)速度较慢但质量更高,而最初的 Nano Banana(google/gemini-2.5-flash-image)是这个昵称最初来源的较旧模型。

图像目录经常变化。模型会被新增、弃用和重新定价,因此你今天固定的 slug 之后可能会被停用。在基于某个模型进行开发之前,请确认它接受图像输入并支持你所需的编辑功能。你可以在 图像模型合集中浏览支持编辑的模型。如需了解目录的完整介绍,请参阅 图像生成模型

下面的示例使用每个请求中所示的 slug,因此你可以按原样运行它们,之后再更改模型。请将你的密钥保存在环境变量中,而不是代码里:

export OPENROUTER_API_KEY="sk-or-..."

你的第一次图像编辑

要编辑图像,请在单个请求中发送源图像和文本指令。编辑后的图像会在响应中返回。以下是一个可运行的 Python 请求,它对本地文件进行编码:

import base64, os, requests

api_key = os.environ["OPENROUTER_API_KEY"]

# Encode a local source image as a base64 data URL.
with open("portrait.jpg", "rb") as f:
    encoded = base64.b64encode(f.read()).decode()
source = f"data:image/jpeg;base64,{encoded}"

resp = requests.post(
    "https://openrouter.ai/api/v1/images",
    headers={"Authorization": f"Bearer {api_key}"},
    json={
        "model": "google/gemini-3.1-flash-image",
        "prompt": "Add a red wool scarf around the person's neck. Keep everything else the same.",
        "input_references": [
            {"type": "image_url", "image_url": {"url": source}}
        ],
    },
)
resp.raise_for_status()

TypeScript 中的相同请求:

import { readFileSync } from "node:fs";

const apiKey = process.env.OPENROUTER_API_KEY!;
const encoded = readFileSync("portrait.jpg").toString("base64");
const source = `data:image/jpeg;base64,${encoded}`;

const resp = await fetch("https://openrouter.ai/api/v1/images", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${apiKey}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    model: "google/gemini-3.1-flash-image",
    prompt: "Add a red wool scarf around the person's neck. Keep everything else the same.",
    input_references: [{ type: "image_url", image_url: { url: source } }],
  }),
});

两种语言的请求体相同。将参考图像放入 input_references,将指令放入 prompt。这就是整个请求。

对输入图像进行编码:base64 或 URL

input_references 字段接受 base64 数据 URL 或 HTTP(S) URL。上面的示例对本地文件进行编码。如果你的图像已经公开托管,直接传入链接并跳过编码即可:

"input_references": [
  {"type": "image_url", "image_url": {"url": "https://example.com/portrait.jpg"}}
]

当图片是公开托管时,请使用 URL,因为这样可以保持请求体较小。对于本地或私有文件,请使用 base64。Gemini 接受 image/pngimage/jpegimage/webpimage/heicimage/heif 输入。支持的格式因模型而异,因此发送前请查看模型页面。

从响应中获取编辑后的图像

API 会将编辑后的图像以 base64 数据的形式返回在 data 数组中。解码 b64_json 值并将其写入文件:

data = resp.json()["data"][0]
with open("edited.png", "wb") as out:
    out.write(base64.b64decode(data["b64_json"]))

TypeScript 版本:

import { writeFileSync } from "node:fs";

const { data } = await resp.json();
writeFileSync("edited.png", Buffer.from(data[0].b64_json, "base64"));

打开 edited.png 查看结果。如果你想要类型化客户端而非原始 HTTP,OpenRouter SDK 提供了一个 images 资源,它调用同一个端点:

from openrouter import OpenRouter

client = OpenRouter(api_key=api_key)
result = client.images.generate(
    model="google/gemini-3.1-flash-image",
    prompt="Add a red wool scarf around the person's neck. Keep everything else the same.",
    input_references=[{"type": "image_url", "image_url": {"url": source}}],
)

使用 pip install openrouter 安装 SDK。它复用之前定义的 api_key,因此无需额外设置。

编写编辑提示词

生成提示词描述一整张新图像。编辑提示词则说明要更改什么、保留什么。先说明更改内容,再指明必须保持不变的部分:

  • 物体替换:“将咖啡杯替换为一杯橙汁。保持手部位置和背景不变。”
  • 背景更换:“将背景更改为夜晚的雪天街道。保持主体完全不变。”
  • 风格迁移:“把这张照片渲染成水彩画。保留构图和主体的姿态。”
  • 文字修复:“把招牌上的文字改成‘OPEN’。匹配原有的字体和颜色。”

你也可以把提示词写成一小段 JSON 文本:

"prompt": "{\"edit\": \"add sunglasses\", \"preserve\": [\"face\", \"hair\", \"lighting\"], \"style\": \"photorealistic\"}"

API 会把它当作纯文本处理,所以这并不是一种特殊模式。这种结构有助于模型区分哪些要改、哪些要保留。可以在你自己的图片上分别试试句子形式和 JSON 形式,哪种效果更好就用哪种。

再次编辑结果

一次编辑并不总能得到你想要的效果。要再跑一遍,就把返回的图片作为下一次的源图传回去。从响应中取出 b64_json 值,把它转成 data URL,然后在下一个 input_references 中传入:

def edit(source_data_url, prompt):
    resp = requests.post(
        "https://openrouter.ai/api/v1/images",
        headers={"Authorization": f"Bearer {api_key}"},
        json={
            "model": "google/gemini-3.1-flash-image",
            "prompt": prompt,
            "input_references": [
                {"type": "image_url", "image_url": {"url": source_data_url}}
            ],
        },
    )
    resp.raise_for_status()
    item = resp.json()["data"][0]
    media_type = item.get("media_type", "image/png")
    return f"data:{media_type};base64,{item['b64_json']}"

step1 = edit(source, "Add a red wool scarf. Keep everything else the same.")
step2 = edit(step1, "Now make the scarf navy blue instead of red.")
step3 = edit(step2, "Add soft morning light coming from the left.")

每次调用都会编辑上一次的结果,因此之前的改动会延续下来。每次调用只给一条指令。小改动更容易检查,出错时也更容易重做。模型不会记住你之前的提示词,所以每次新的提示词里都要重复那些应当保持不变的部分。

更换编辑模型

要把同一个编辑请求发给另一个模型,只需更改 model 字段。源图、提示词以及响应处理代码都保持不变:

json={
    "model": "openai/gpt-5-image",  # was google/gemini-3.1-flash-image
    "prompt": "Add a red wool scarf. Keep everything else the same.",
    "input_references": [
        {"type": "image_url", "image_url": {"url": source}}
    ],
},

使用google/gemini-3.1-flash-image作为快速的默认选择。当你想要最低价格时,使用google/gemini-3.1-flash-lite-image。当你想要更高质量并能接受更高延迟时,使用google/gemini-3-pro-image。原有的google/gemini-2.5-flash-image仍可使用相同的请求结构,但上述更新的模型是更好的默认选择。当你想要openai/gpt-5-image时,使用来自其他提供商的模型,例如比较质量、成本或速度在你自己的图像上。这一单字段的更改仅适用于接受图像输入并支持相同input_references结构的模型,因此在切换之前请确认该模型具备编辑能力。

要按环境设置模型及其选项,而不是在代码中设置,请使用 OpenRouter Presets

错误与成本

这些失败足够常见,值得提前规划应对:

  • 不支持的输入。模型可能会拒绝它不支持的图片格式,也可能拒绝它无法访问的 URL。发送前请检查文件类型和 URL。
  • 图片过大。大文件可能会超时或失败。请先缩小图片,因为大多数编辑并不需要 4000 万像素的源图。
  • 返回文本而非图片。像“这张照片里有什么?”这样的提问可能会让模型用文本作答,而不是生成图片。API 会将其作为 400 错误返回,例如 Gemini could not generate an image (STOP),而不是空响应。请改写为指令而非提问,并在解码前检查 HTTP 状态码。

当用量数据可用时,响应会以美元报告每个请求的成本。将其记录下来以跟踪支出:

usage = resp.json().get("usage")
if usage:
    print(f"This edit cost ${usage['cost']}")

对于批处理任务,请遵守速率限制。对 429 和 5xx 响应进行重试,并在每次尝试之间逐步延长延迟,同时限制同时运行的编辑数量。在开始下一次编辑之前保存每一张返回的图像,这样即使某次失败也不会丢失已完成的工作。

后续步骤

复制第一个请求,换成你自己的图像,然后运行一次编辑。如果想改为根据文本生成图像,请参阅图像生成文档。要查找当前支持编辑的模型,请浏览图像模型合集

常见问题

我可以用 Gemini API 编辑图像吗?

可以。通过 OpenRouter API 向 google/gemini-3.1-flash-image 发送一个请求,其中包含源图像和文本指令,编辑后的图像会以 base64 形式在响应中返回。该模型是 Nano Banana 2。整个请求一屏就能放下,你可以用 Python、TypeScript 或 curl 运行它。

图像生成和图像编辑有什么区别?

图像编辑是对已有图像进行修改。图像生成则是根据文本创建新图像。每个编辑请求都包含 input_references 中的源图像,以及一条说明要更改什么、保留什么的指令。如果你的请求没有源图像,仅凭文本提示词生成,那就是生成。

如何向 API 发送图像,用 URL 还是 base64?

input_references 字段接受用于本地或私有文件的 base64 数据 URL,或用于公开托管图像的普通 HTTP(S) URL。当图像已经在线时,使用 URL 形式可以保持请求体积较小;当文件在你的机器上时,使用 base64 形式。Gemini 接受 png、jpeg、webp、heic 和 heif 输入(image/pngimage/jpegimage/webpimage/heicimage/heif)。支持的格式因模型而异,因此发送前请查看模型页面。

我可以使用 Gemini 以外的模型来编辑图像吗?

可以。更改 model 字段,其余请求保持不变。请先查看 图像模型集合,因为编辑支持、价格和速度因模型而异。

如何提示 AI 模型编辑图像?

先描述要更改的内容,然后说明要保留的内容,例如“把背景改成夜晚的雪街。主体保持原样。”每个请求只给一条指令效果最好。为了获得精确结果,请以小步骤进行编辑,并将每次返回的图像作为下一个提示词的源图像发回。

参考文献

来源:OpenRouter:Announcements(RSS)· openrouter.ai