NanoBanana Pro Edit
Image editing uses the same Gemini API (generateContent) as NanoBanana Pro image generation. You send the original image + edit instruction in the request and receive the edited image in the response. See Gemini docs: Image editing.
Endpoint: Same as generation: POST https://aiberm.com/v1beta/models/gemini-3-pro-image-preview:generateContent.
Key points: Put an image part (inlineData) and a text part (edit instruction) in contents; set generationConfig.responseModalities to ["TEXT", "IMAGE"] to get the edited image; read the result from candidates[0].content.parts → inline_data.
Example code
Python uses snake_case; REST/cURL uses camelCase. Same meaning.
1from google import genai2from google.genai import types3from PIL import Image4from io import BytesIO5 6base_url = "https://aiberm.com"7api_key = "YOUR_API_KEY"8model = "gemini-3-pro-image-preview"9output_file = "edited.png"10 11image_path = "original.png"12edit_prompt = "Add a stylish top hat to this image, keep the rest unchanged."13 14client = genai.Client(15 api_key=api_key,16 http_options=types.HttpOptions(api_version="v1beta", base_url=base_url),17)18image = Image.open(image_path)19 20response = client.models.generate_content(21 model=model,22 contents=[edit_prompt, image],23 config=types.GenerateContentConfig(24 response_modalities=["TEXT", "IMAGE"],25 ),26)27 28for part in response.parts:29 if part.text is not None:30 print(part.text)31 elif part.inline_data is not None:32 Image.open(BytesIO(part.inline_data.data)).save(output_file)33 print(f"Saved edited image: {output_file}")Edit vs generate
| Generate (NanoBanana Pro) | Edit (this page) | |
|---|---|---|
contents | Text only (describe the image to create) | Image + text (describe how to edit) |
generationConfig.imageConfig | Required (aspect ratio, 1K/2K/4K) | Optional for edit |
responseModalities | ["IMAGE"] or ["TEXT","IMAGE"] | Typically ["TEXT","IMAGE"] |
Same endpoint and auth; only contents and whether you pass imageConfig differ. For more parameters see NanoBanana Pro.
Multiple images
Put several image parts in contents.parts (one inlineData per image), then one text part with the edit instruction. The model uses all images and the instruction to produce the result (e.g. “compose the subject from the first image onto the background of the second”).
Python: pass multiple image objects and one text in contents.
image1 = Image.open("photo.png")
image2 = Image.open("background.png")
response = client.models.generate_content(
model=model,
contents=["Place the person from the first image onto the background of the second.", image1, image2],
config=types.GenerateContentConfig(response_modalities=["TEXT", "IMAGE"]),
)
cURL: in contents[0].parts, add one inlineData per image, then one text.
"contents": [{
"parts": [
{ "inlineData": { "mimeType": "image/png", "data": "<BASE64_IMAGE1>" }},
{ "inlineData": { "mimeType": "image/png", "data": "<BASE64_IMAGE2>" }},
{ "text": "Place the person from the first image onto the background of the second." }
]
}]
Using an image URL
The API only accepts inlineData (base64) or fileData (via the File API); it does not accept image URLs directly. For images at a URL, download them first and then include them in the request.
Python: download from URL and pass the image to the SDK (the SDK will encode it as needed).
import requests
from io import BytesIO
image_url = "https://example.com/photo.jpg"
resp = requests.get(image_url)
image = Image.open(BytesIO(resp.content))
response = client.models.generate_content(
model=model,
contents=["Add a top hat to this image.", image],
config=types.GenerateContentConfig(response_modalities=["TEXT", "IMAGE"]),
)
cURL: download the image from the URL, convert it to base64, then put the result in inlineData.data.