Gemini Nano Banana 2.1 图片编辑
通过 Gemini Nano Banana 2.1 模型,根据文字提示修改输入图片,支持 1K、2K、4K 分辨率、宽高比配置和思考等级配置。本文使用 DMXAPI 兼容的 Gemini 原生调用格式,提供 SDK 和 requests 两种写法。
模型升级说明
Gemini Nano Banana 2.1 是 Nano Banana 2(Gemini 3.1 Flash Image)的更新版本。Google 官方说明其改善了视觉质量、写实性、提示遵循、文字排版及多轮角色一致性。
本模型支持 1K / 2K / 4K,不支持 512;Thinking 支持 minimal / medium / high,默认 medium。
接口地址
https://www.dmxapi.cn/v1beta/models/gemini-nano-banana-2.1:generateContent注意
请妥善保管 DMXAPI API Key,不要将真实密钥提交到公开仓库。使用 SDK 示例前,请更新 google-genai
模型名称
Gemini Nano Banana 2.1
- 模型名称:
gemini-nano-banana-2.1 - 别名:Nano Banana 2.1
- 特点:使用文字提示与输入图片进行图片编辑。
- 配置:支持 1K / 2K / 4K 分辨率及 Thinking 思考等级。
示例代码
python
"""
╔═══════════════════════════════════════════════════════════════════════════════╗
║ ║
║ DMXAPI 图片编辑工具 (gemini-nano-banana-2.1 · SDK 版) ║
║ ║
╠═══════════════════════════════════════════════════════════════════════════════╣
║ ║
║ 功能说明: ║
║ ──────── ║
║ • 使用 google-genai SDK 调用 DMXAPI 的 Gemini 原生兼容接口 ║
║ • 根据文字提示和输入图片进行图片编辑 (图生图) ║
║ • 支持 1K / 2K / 4K 分辨率、宽高比配置和思考等级配置 ║
║ • 编辑后的图片自动保存到 output 文件夹 ║
║ ║
║ 使用模型: gemini-nano-banana-2.1 ║
║ ║
╚═══════════════════════════════════════════════════════════════════════════════╝
"""
# ══════════════════════════════════════════════════════════════════════════════
# 依赖导入
# ══════════════════════════════════════════════════════════════════════════════
from datetime import datetime # 日期时间处理,用于生成带时间戳的文件名
from pathlib import Path # 文件路径处理,用于创建输出目录、保存图片
from google import genai # Google GenAI SDK,用于调用 Gemini 原生接口
from google.genai import types # SDK 配置类型: 生成配置 / 图片配置 / 思考配置
from PIL import Image # 图片处理库,用于读取输入图片
# 提示: part.as_image() 依赖 Pillow 保存图片,请先安装依赖: pip install google-genai Pillow
# ══════════════════════════════════════════════════════════════════════════════
# API 配置
# ══════════════════════════════════════════════════════════════════════════════
API_KEY = "sk-****************************************" # DMXAPI 密钥,请替换为你自己的密钥
BASE_URL = "https://www.dmxapi.cn" # DMXAPI 基础地址,SDK 会自动拼接接口路径
MODEL_NAME = "gemini-nano-banana-2.1" # 模型名称,可按需修改为其他图像模型
# ══════════════════════════════════════════════════════════════════════════════
# 输入图片配置
# ══════════════════════════════════════════════════════════════════════════════
# 待编辑图片的路径,请先将图片保存到当前目录
INPUT_IMAGE_PATH = "./b1.png" # 替换为你要修改的图片路径
# ══════════════════════════════════════════════════════════════════════════════
# 创建 API 客户端
# ══════════════════════════════════════════════════════════════════════════════
# genai.Client 是 SDK 的统一入口,后续所有模型调用都通过它发起
client = genai.Client(
api_key=API_KEY, # 身份验证: 使用 DMXAPI 密钥
http_options={"base_url": BASE_URL}, # 关键配置: 将 SDK 默认的 Google 地址改为 DMXAPI
)
# ══════════════════════════════════════════════════════════════════════════════
# 构建请求参数
# ══════════════════════════════════════════════════════════════════════════════
# 读取需要编辑的图片
image = Image.open(INPUT_IMAGE_PATH)
# 【必填】编辑提示词,描述需要对图片进行的修改
prompt = "让图里的人手里拿着鲜花,保留其他细节。"
# GenerateContentConfig: 一次生成请求的全部配置 (SDK 使用下划线命名)
config = types.GenerateContentConfig(
# response_modalities: 设置返回内容的类型
# - ["IMAGE"]: 只返回图片 (本例)
# - ["TEXT", "IMAGE"]: 同时返回文字说明和图片
response_modalities=["IMAGE"],
# image_config: 图片输出配置
image_config=types.ImageConfig(
# aspect_ratio: 设置输出图片的宽高比
#
# ┌────────────────────────────────────────────────────────────┐
# │ gemini-nano-banana-2.1 │
# ├──────────┬─────────────┬────────┬─────────────┬────────────┤
# │ 宽高比 │ 1K 分辨率 │ 1K令牌 │ 2K 分辨率 │ 4K 分辨率 │
# ├──────────┼─────────────┼────────┼─────────────┼────────────┤
# │ 1:1 │ 1024x1024 │ 1120 │ 2048x2048 │ 4096x4096 │
# │ 1:4 │ 512x2048 │ 1120 │ 1024x4096 │ 2048x8192 │
# │ 1:8 │ 384x3072 │ 1120 │ 768x6144 │ 1536x12288 │
# │ 2:3 │ 848x1264 │ 1120 │ 1696x2528 │ 3392x5056 │
# │ 3:2 │ 1264x848 │ 1120 │ 2528x1696 │ 5056x3392 │
# │ 3:4 │ 896x1200 │ 1120 │ 1792x2400 │ 3584x4800 │
# │ 4:1 │ 2048x512 │ 1120 │ 4096x1024 │ 8192x2048 │
# │ 4:3 │ 1200x896 │ 1120 │ 2400x1792 │ 4800x3584 │
# │ 4:5 │ 928x1152 │ 1120 │ 1856x2304 │ 3712x4608 │
# │ 5:4 │ 1152x928 │ 1120 │ 2304x1856 │ 4608x3712 │
# │ 8:1 │ 3072x384 │ 1120 │ 6144x768 │ 12288x1536 │
# │ 9:16 │ 768x1376 │ 1120 │ 1536x2752 │ 3072x5504 │
# │ 16:9 │ 1376x768 │ 1120 │ 2752x1536 │ 5504x3072 │
# │ 21:9 │ 1584x672 │ 1120 │ 3168x1344 │ 6336x2688 │
# └──────────┴─────────────┴────────┴─────────────┴────────────┘
# 注: 1K/2K/4K令牌分别为1120/1680/3780
aspect_ratio="1:1",
# image_size: 设置输出图片的分辨率
# - "1K": 1K 分辨率 (默认值)
# - "2K": 2K 分辨率
# - "4K": 4K 分辨率
# 注意: K 必须大写,不能写成 1k;本模型不支持 512
image_size="1K",
),
# thinking_config: 思考等级配置 (思考过程默认启用,无法完全关闭)
thinking_config=types.ThinkingConfig(
# thinking_level: 生成图片前的思考深度
# - ThinkingLevel.MINIMAL: 较少思考,速度最快
# - ThinkingLevel.MEDIUM: 均衡模式 (默认值)
# - ThinkingLevel.HIGH: 深度思考,复杂画面质量更稳定
thinking_level=types.ThinkingLevel.MEDIUM,
),
# tools: Google 搜索工具(可选)
# - 使用实时信息修改图像(如根据最新资讯添加元素等)
# 示例: tools=[{"google_search": {}}]
#
# 本模型同时支持 Image Search(图片搜索):
# tools=[types.Tool(google_search=types.GoogleSearch(
# search_types=types.SearchTypes(
# web_search=types.WebSearch(),
# image_search=types.ImageSearch()
# )
# ))]
)
# ══════════════════════════════════════════════════════════════════════════════
# 主程序执行
# ══════════════════════════════════════════════════════════════════════════════
# ┌─────────────────────────────────────────────────────────────────────────┐
# │ 步骤 1: 创建输出文件夹 │
# │ 检查 output 目录是否存在,不存在则创建 │
# └─────────────────────────────────────────────────────────────────────────┘
output_dir = Path("output")
output_dir.mkdir(exist_ok=True)
# ┌─────────────────────────────────────────────────────────────────────────┐
# │ 步骤 2: 发送 API 请求 │
# │ 调用 generate_content 方法,传入提示词、图片和生成配置 │
# └─────────────────────────────────────────────────────────────────────────┘
response = client.models.generate_content(
model=MODEL_NAME, # 【必填】模型名称,使用上面 API 配置区的 MODEL_NAME
contents=[prompt, image], # 【必填】输入内容: 编辑提示词 + 原始图片
config=config, # 上面构建的生成配置
)
# ┌─────────────────────────────────────────────────────────────────────────┐
# │ 步骤 3: 解析响应并保存图片 │
# │ 遍历返回的每个内容片段,跳过思考内容,保存图片数据 │
# └─────────────────────────────────────────────────────────────────────────┘
for part in response.parts or []:
# 跳过思考过程中的临时内容,只处理最终结果
if part.thought:
continue
# 文字片段 (仅 response_modalities 包含 TEXT 时返回)
if part.text is not None:
print(part.text)
# 图片片段 (inline_data 内嵌图片数据)
elif part.inline_data is not None:
# 按返回的 MIME 类型确定文件扩展名 (image/jpeg -> jpeg)
extension = part.inline_data.mime_type.split("/")[-1]
# 生成带时间戳的文件名,扩展名与返回的图片格式一致
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
filename = f"output/edited_image_{timestamp}.{extension}"
# as_image() 取出图片对象,save() 将原始图片字节写入文件
part.as_image().save(filename)
# 输出保存成功的提示信息
print(f"修改后的图片已保存到 {filename}")python
"""
╔═══════════════════════════════════════════════════════════════════════════════╗
║ ║
║ DMXAPI 图片编辑工具 (gemini-nano-banana-2.1 · requests 版) ║
║ ║
╠═══════════════════════════════════════════════════════════════════════════════╣
║ ║
║ 功能说明: ║
║ ──────── ║
║ • 使用 requests 库直接调用 DMXAPI 的 Gemini 原生兼容接口 ║
║ • 根据文字提示和输入图片进行图片编辑 (图生图) ║
║ • 支持 1K / 2K / 4K 分辨率、宽高比配置和思考等级配置 ║
║ • 编辑后的图片自动保存到 output 文件夹 ║
║ ║
║ 使用模型: gemini-nano-banana-2.1 ║
║ ║
╚═══════════════════════════════════════════════════════════════════════════════╝
"""
# ══════════════════════════════════════════════════════════════════════════════
# 依赖导入
# ══════════════════════════════════════════════════════════════════════════════
import requests # HTTP 请求库,用于调用 API 接口
import base64 # Base64 编解码,用于处理图片数据
from datetime import datetime # 日期时间处理,用于生成带时间戳的文件名
from pathlib import Path # 文件路径处理,用于创建输出目录、保存图片
# 提示: 请先安装依赖: pip install requests
# ══════════════════════════════════════════════════════════════════════════════
# API 配置
# ══════════════════════════════════════════════════════════════════════════════
API_KEY = "sk-****************************************" # DMXAPI 密钥,请替换为你自己的密钥
BASE_URL = "https://www.dmxapi.cn/v1beta" # DMXAPI 基础地址
MODEL_NAME = "gemini-nano-banana-2.1" # 模型名称,可按需修改为其他图像模型
# 完整的 API 端点由基础地址和模型名称拼接而成,无需手动填写完整地址
API_URL = f"{BASE_URL}/models/{MODEL_NAME}:generateContent"
# ══════════════════════════════════════════════════════════════════════════════
# 输入图片配置
# ══════════════════════════════════════════════════════════════════════════════
# 待编辑图片的路径,请先将图片保存到当前目录
INPUT_IMAGE_PATH = "./b1.png" # 替换为你要修改的图片路径
# ══════════════════════════════════════════════════════════════════════════════
# HTTP 请求头配置
# ══════════════════════════════════════════════════════════════════════════════
headers = {
"x-goog-api-key": API_KEY, # 身份验证: Gemini 原生格式的密钥请求头
"Content-Type": "application/json", # 内容类型: JSON 数据格式
}
# ══════════════════════════════════════════════════════════════════════════════
# 构建请求参数
# ══════════════════════════════════════════════════════════════════════════════
# 读取图片并编码为 Base64;本例输入为 PNG,mimeType 必须与图片实际格式一致
image_data = base64.b64encode(Path(INPUT_IMAGE_PATH).read_bytes()).decode("utf-8")
payload = {
# 【必填】contents: 对话内容列表,包含编辑提示词和原始图片
"contents": [{
"role": "user",
"parts": [
# 【必填】parts[].text: 编辑提示词
{"text": "让图里的人手里拿着鲜花,保留其他细节。"},
{
# 【必填】inlineData: 输入图片的 MIME 类型和 Base64 数据
"inlineData": {
"mimeType": "image/png",
"data": image_data,
},
},
],
}],
# generationConfig: 生成配置 (HTTP JSON 使用驼峰命名)
"generationConfig": {
# responseModalities: 设置返回内容的类型
# - ["IMAGE"]: 只返回图片 (本例)
# - ["TEXT", "IMAGE"]: 同时返回文字说明和图片
"responseModalities": ["IMAGE"],
# imageConfig: 图片输出配置
"imageConfig": {
# aspectRatio: 设置输出图片的宽高比
#
# ┌────────────────────────────────────────────────────────────┐
# │ gemini-nano-banana-2.1 │
# ├──────────┬─────────────┬────────┬─────────────┬────────────┤
# │ 宽高比 │ 1K 分辨率 │ 1K令牌 │ 2K 分辨率 │ 4K 分辨率 │
# ├──────────┼─────────────┼────────┼─────────────┼────────────┤
# │ 1:1 │ 1024x1024 │ 1120 │ 2048x2048 │ 4096x4096 │
# │ 1:4 │ 512x2048 │ 1120 │ 1024x4096 │ 2048x8192 │
# │ 1:8 │ 384x3072 │ 1120 │ 768x6144 │ 1536x12288 │
# │ 2:3 │ 848x1264 │ 1120 │ 1696x2528 │ 3392x5056 │
# │ 3:2 │ 1264x848 │ 1120 │ 2528x1696 │ 5056x3392 │
# │ 3:4 │ 896x1200 │ 1120 │ 1792x2400 │ 3584x4800 │
# │ 4:1 │ 2048x512 │ 1120 │ 4096x1024 │ 8192x2048 │
# │ 4:3 │ 1200x896 │ 1120 │ 2400x1792 │ 4800x3584 │
# │ 4:5 │ 928x1152 │ 1120 │ 1856x2304 │ 3712x4608 │
# │ 5:4 │ 1152x928 │ 1120 │ 2304x1856 │ 4608x3712 │
# │ 8:1 │ 3072x384 │ 1120 │ 6144x768 │ 12288x1536 │
# │ 9:16 │ 768x1376 │ 1120 │ 1536x2752 │ 3072x5504 │
# │ 16:9 │ 1376x768 │ 1120 │ 2752x1536 │ 5504x3072 │
# │ 21:9 │ 1584x672 │ 1120 │ 3168x1344 │ 6336x2688 │
# └──────────┴─────────────┴────────┴─────────────┴────────────┘
# 注: 1K/2K/4K令牌分别为1120/1680/3780
"aspectRatio": "1:1",
# imageSize: 设置输出图片的分辨率
# - "1K": 1K 分辨率 (默认值)
# - "2K": 2K 分辨率
# - "4K": 4K 分辨率
# 注意: K 必须大写,不能写成 1k;本模型不支持 512
"imageSize": "1K",
},
# thinkingConfig: 思考等级配置 (思考过程默认启用,无法完全关闭)
"thinkingConfig": {
# thinkingLevel: 生成图片前的思考深度
# - "MINIMAL": 较少思考,速度最快
# - "MEDIUM": 均衡模式 (默认值)
# - "HIGH": 深度思考,复杂画面质量更稳定
"thinkingLevel": "MEDIUM",
},
},
# tools: Google 搜索工具(可选)
# - 使用实时信息修改图像(如根据最新资讯添加元素等)
# "tools": [{"google_search": {}}]
#
# 本模型同时支持 Image Search(图片搜索):
# "tools": [{"google_search": {"search_types": {"web_search": {}, "image_search": {}}}}]
}
# ══════════════════════════════════════════════════════════════════════════════
# 主程序执行
# ══════════════════════════════════════════════════════════════════════════════
# ┌─────────────────────────────────────────────────────────────────────────┐
# │ 步骤 1: 创建输出文件夹 │
# │ 检查 output 目录是否存在,不存在则创建 │
# └─────────────────────────────────────────────────────────────────────────┘
output_dir = Path("output")
output_dir.mkdir(exist_ok=True)
# ┌─────────────────────────────────────────────────────────────────────────┐
# │ 步骤 2: 发送 API 请求 │
# │ 向 DMXAPI 发送 POST 请求,地址由 BASE_URL 和 MODEL_NAME 拼接 │
# └─────────────────────────────────────────────────────────────────────────┘
response = requests.post(API_URL, headers=headers, json=payload)
response.raise_for_status() # 检查 HTTP 状态码,若有错误则抛出异常
# ┌─────────────────────────────────────────────────────────────────────────┐
# │ 步骤 3: 解析响应并保存图片 │
# │ 遍历 candidates 下的每个 part,解码 Base64 图片数据并保存 │
# └─────────────────────────────────────────────────────────────────────────┘
result = response.json()
for candidate in result.get("candidates", []): # 遍历候选结果
for part in candidate.get("content", {}).get("parts", []):
# 跳过思考过程中的临时内容,只处理最终结果
if part.get("thought"):
continue
# 文字片段 (仅 responseModalities 包含 TEXT 时返回)
if "text" in part:
print(part["text"])
# 图片片段 (inlineData 内嵌 Base64 图片数据)
elif "inlineData" in part:
image = part["inlineData"]
# 按返回的 MIME 类型确定文件扩展名 (image/png -> png)
extension = image["mimeType"].split("/")[-1]
# 生成带时间戳的文件名,格式: edited_image_20261008_120000.jpeg
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
filename = f"output/edited_image_{timestamp}.{extension}"
# 解码 Base64 数据并写入图片文件
Path(filename).write_bytes(base64.b64decode(image["data"]))
# 输出保存成功的提示信息
print(f"修改后的图片已保存到 {filename}")返回示例
text
修改后的图片已保存到 output/edited_image_20261008_120000.jpegtext
修改后的图片已保存到 output/edited_image_20261008_120000.jpeg© 2026 DMXAPI gemini-nano-banana-2.1 图片编辑
