如何透過 OpenRouter API 使用 Gemini 編輯圖片
Nano Banana API: Edit Images with Gemini in Code
本文介紹如何透過 OpenRouter API 與 google/gemini-3.1-flash-image 進行圖片編輯,並提供 Python 與 TypeScript 的完整程式碼範例。
原文提供透過 API 編輯圖片的程式碼範例與實作細節,讀者可據此評估如何整合至現有工作流程。
本指南說明如何在程式碼中使用文字提示編輯影像。您透過 OpenRouter API 將來源影像和編輯提示送至 google/gemini-3.1-flash-image,編輯後的影像會回傳於回應中。『Nano Banana』是 Google Gemini 影像模型的暱稱。此 slug 為 Nano Banana 2,該系列的預設快速模型。因為您是透過 一個 API 進入,之後可以藉由變更一個欄位來使用不同的編輯模型。
影像編輯會改變現有的影像。影像生成則是從文字產生全新的影像。本指南涵蓋編輯功能,因此此處的每個請求都包含來源影像。若要從文字建立影像,請參閱 影像生成檔案 或 影像生成教學。

TL;DR
- 編輯只需一次請求。將來源影像放於
input_references,指令放於prompt,然後從data[0].b64_json讀取編輯後的影像並解碼至磁碟。 google/gemini-3.1-flash-image為 Nano Banana 2,預設的快速 Gemini 影像模型。在使用前請確認模型是否接受影像輸入,因為編輯支援程度不同。- 對於本地或私有檔案,請以 base64 資料 URL 方式傳送輸入;對於已託管的影像,則使用純 HTTP(S) URL。
- 分階段編輯。將每次回傳的影像再次作為下一個來源,並一次呼叫一條指令,這樣改動會疊加。
- 透過編輯一個欄位來切換編輯模型。
先決條件
您需要三樣東西:
- 來自 金鑰頁面 的 OpenRouter API 金鑰以及基礎 URL
https://openrouter.ai/api/v1。 - 一個 HTTP 客戶端。範例使用 Python
requests和 TypeScriptfetch。您也可以使用 curl 或 OpenRouter SDK。任何能送出帶 Authorization 標頭的 JSON POST 的客戶端皆可。 - 來源影像,可為本機檔案或公開 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/png、image/jpeg、image/webp、image/heic 與 image/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 值,將其轉換為資料 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。
- 影像過大。大型檔案可能逾時或失敗。先縮小影像,因為大多數編輯不需要 40 兆畫素的來源。
- 文字而非影像。像「這張照片裡是什麼?」這類問題可能會使模型以文字回覆而非產生影像。API 會以
400錯誤回傳,例如Gemini could not generate an image (STOP),而非空回應。請改寫為指示而非提問,並在解碼前檢查 HTTP 狀態。
回應會在可用使用量資料時以 USD 報告每個請求的成本。請將其記錄以追蹤支出:
usage = resp.json().get("usage")
if usage:
print(f"This edit cost ${usage['cost']}")對於批次工作,請遵守 速率限制。對 429 與 5xx 回應重試時,逐次增加延遲,並限制同時執行的編輯數量。每次取得圖片後先儲存,再進行下一次編輯,避免一次失敗造成已完成的工作遺失。
後續步驟
複製第一個請求,使用自己的圖片並執行編輯。若要改為從文字產生圖片,請參閱 圖片產生檔案。要查詢目前支援編輯的模型,請瀏覽 圖片模型集合。
常見問題
我能使用 Gemini API 編輯圖片嗎?
可以。將原始圖片和文字指令一起送至 google/gemini-3.1-flash-image 的 OpenRouter API,編輯後的圖片會以 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/png、image/jpeg、image/webp、image/heic、image/heif)。支援格式依模型而異,請於送出前檢視模型頁面。
我能使用非 Gemini 的模型來編輯圖片嗎?
可以。改變 model 欄位,其他請求保持不變。請先查閱 圖片模型集合,因為編輯支援、價格與速度因模型而異。
如何提示 AI 模型編輯圖片?
先描述要更改的內容,再說明要保留什麼,例如「將背景改為夜晚的雪景街道。保持主體不變。」每個請求只使用一條指令效果最佳。若需精準結果,請分小步驟編輯,並將每次回傳的圖片作為下一個提示的來源。
參考資料
- OpenRouter API 金鑰:建立並管理每次請求使用的金鑰。
- 圖片模型集合:所有支援編輯的模型及其輸入支援。
- 圖片產生檔案:關於從文字產生圖片的同類指南。
- 預設值指南:為每個環境固定模型及其選項,而非在程式碼中設定。
來源:openrouter blog · openrouter.ai