How to enforce Ratio or Size with Nano Banana?

Hey folks,

I’l facing a little challenge here. I am trying to produce images with Nano Banana and end up with a ratio / size challenge.

I understand that the current API does not offer any parameter to control that. And from what I’ve read so far, it seems the only way to push the model in the right direction is to set-it at the prompt level.

I have tried several approaches, include json prompt and strict guideline prompting. I also tried image generation from scratch or image editing using my attached image as a reference to enforce the right ratio, etc.

Still, despite my best efforts, the model systematically renders a 1632x640 image in the end.

Do you have any idea, best practice or reco to tackle that? I understand it won’t be perfect, but I’m just trying to get rid of that rigid 1632x640 size thing for now.

In case that’s worth, here is my test code below.

Thanks a lot

 2. Set the local paths to your two reference images.
IMAGE_PATH_1 = "reference_image.png"
IMAGE_PATH_2 = "insertion_image.png"

# 3. Define your final text prompt.
USER_PROMPT = """
  {
  "rendering_protocol": "xxxxx",
  "instruction": "xxxx",
  "layout_framing": "xxxx",
  "compliance": "xxxxx.",
  "negative_prompt": "xxxx",
  "aspect_ratio": "1:1"
  }


 
 """

# 4. Set the base name for the output files.
OUTPUT_FILE_NAME = "generated_output"

################################################################################
# 🔚 END CONFIGURATION
################################################################################


def save_binary_file(file_name, data):
    """Saves raw binary data to a file."""
    with open(file_name, "wb") as f:
        f.write(data)
    print(f"File saved to: {file_name}")


def generate():
    """Main function to configure the client and generate content."""
    
    # Check if image paths are valid before proceeding
    for path in [IMAGE_PATH_1, IMAGE_PATH_2]:
        if not os.path.exists(path):
            raise FileNotFoundError(f"Error: Image file not found at '{path}'")

    client = genai.Client(api_key=API_KEY)

    # Read image files and determine their MIME types
    mime_type_1, _ = mimetypes.guess_type(IMAGE_PATH_1)
    with open(IMAGE_PATH_1, "rb") as f:
        image_data_1 = f.read()

    mime_type_2, _ = mimetypes.guess_type(IMAGE_PATH_2)
    with open(IMAGE_PATH_2, "rb") as f:
        image_data_2 = f.read()

    model = "gemini-2.5-flash-image-preview"
    contents = [
        types.Content(
            role="user",
            parts=[
                types.Part.from_bytes(
                    mime_type=mime_type_1,
                    data=image_data_1,
                ),
                types.Part.from_text(text="""Generate a persona wearing that belt for relaxation"""),
            ],
        ),
        types.Content(
            role="model",
            parts=[
                types.Part.from_bytes(
                    mime_type=mime_type_2,
                    data=image_data_2,
                ),
            ],
        ),
        types.Content(
            role="user",
            parts=[
                types.Part.from_text(text=USER_PROMPT),
            ],
        ),
    ]
    generate_content_config = types.GenerateContentConfig(
        response_modalities=[
            "IMAGE",
            "TEXT",
        ],
    )

    print("Generating content... 🖼️")
    file_index = 0
    for chunk in client.models.generate_content_stream(
        model=model,
        contents=contents,
        config=generate_content_config,
    ):
        if (
            chunk.candidates is None
            or not chunk.candidates[0].content
            or not chunk.candidates[0].content.parts
        ):
            continue
        
        part = chunk.candidates[0].content.parts[0]
        if part.inline_data and part.inline_data.data:
            file_name_base = f"{OUTPUT_FILE_NAME}_{file_index}"
            inline_data = part.inline_data
            data_buffer = inline_data.data
            file_extension = mimetypes.guess_extension(inline_data.mime_type) or ".bin"
            save_binary_file(f"{file_name_base}{file_extension}", data_buffer)
            file_index += 1
        elif chunk.text:
            print(chunk.text, end="", flush=True)
    print("\nGeneration complete. ✨")


if __name__ == "__main__":
    generate()
3 Likes

Ive had the same issue it seems to be a limitation of the model (currently). I am attempting to intelligently resize images to a specific aspect ratio and it will always re-use the source images dimensions. it’s probably just a “wait for them to fix it” kind of deal.

If you add a second image , your ‘scene’, and make sure that is the last image added to the prompt, it’s aspect ratio will be used.