> ## Documentation Index
> Fetch the complete documentation index at: https://apidoc.cometapi.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Usare i modelli immagine Gemini

> Chiama i modelli immagine Gemini (Nano Banana 2 / Pro) su CometAPI usando il Google Gen AI SDK per text-to-image, image-to-image e composizione multi-immagine.

Questa guida mostra come usare i modelli immagine Gemini tramite CometAPI usando il **Google Gen AI SDK**. Include:

* Generazione text-to-image
* Modifica image-to-image
* Composizione multi-immagine
* Salvataggio delle immagini generate

<Info>
  - **Base URL:** `https://api.cometapi.com`
  - Installa l'SDK: `pip install google-genai` (Python) o `npm install @google/genai` (Node.js)
</Info>

***

## Configurazione

Inizializza il client con il base URL di CometAPI:

<CodeGroup>
  ```python Python theme={null}
  from google import genai
  from google.genai import types
  import os

  COMETAPI_KEY = os.environ["COMETAPI_KEY"]

  client = genai.Client(
      http_options={"api_version": "v1beta", "base_url": "https://api.cometapi.com"},
      api_key=COMETAPI_KEY,
  )
  ```

  ```javascript Node.js theme={null}
  import { GoogleGenAI } from "@google/genai";

  const COMETAPI_KEY = process.env.COMETAPI_KEY;

  const ai = new GoogleGenAI({
    apiKey: COMETAPI_KEY,
    httpOptions: { apiVersion: "v1beta", baseUrl: "https://api.cometapi.com" },
  });
  ```

  ```go Go theme={null}
  package main

  import (
  	"context"
  	"os"
  	"google.golang.org/genai"
  )

  func main() {
  	ctx := context.Background()
  	apiKey := os.Getenv("COMETAPI_KEY")

  	client, _ := genai.NewClient(ctx, &genai.ClientConfig{
  		APIKey:  apiKey,
  		Backend: genai.BackendGeminiAPI,
  		HTTPOptions: genai.HTTPOptions{
  			BaseURL: "https://api.cometapi.com",
  		},
  	})
  	// use client below...
  }
  ```
</CodeGroup>

***

## Generazione text-to-image

Genera un'immagine a partire da un prompt di testo e salvala in un file.

<CodeGroup>
  ```python Python theme={null}
  from google import genai
  from google.genai import types
  from PIL import Image
  import os

  client = genai.Client(
      http_options={"api_version": "v1beta", "base_url": "https://api.cometapi.com"},
      api_key=os.environ.get("COMETAPI_KEY"),
  )

  response = client.models.generate_content(
      model="gemini-3.1-flash-image-preview",
      contents="Create a picture of a nano banana dish in a fancy restaurant with a Gemini theme",
      config=types.GenerateContentConfig(
          response_modalities=["TEXT", "IMAGE"],
      ),
  )

  final_image = None
  for part in response.parts:
      if getattr(part, "thought", False):
          continue
      if part.text is not None:
          print(part.text)
      elif part.inline_data is not None:
          final_image = part.as_image()

  if final_image:
      final_image.save("generated_image.png")
      print("Image saved to generated_image.png")
  ```

  ```javascript Node.js theme={null}
  import { GoogleGenAI } from "@google/genai";
  import * as fs from "fs";

  const ai = new GoogleGenAI({
    apiKey: process.env.COMETAPI_KEY,
    httpOptions: { apiVersion: "v1beta", baseUrl: "https://api.cometapi.com" },
  });

  const response = await ai.models.generateContent({
    model: "gemini-3.1-flash-image-preview",
    contents: "Create a picture of a nano banana dish in a fancy restaurant with a Gemini theme",
    config: { responseModalities: ["TEXT", "IMAGE"] },
  });

  let finalImagePart;
  for (const part of response.candidates[0].content.parts) {
    if (part.thought === true) {
      continue;
    }
    if (part.text) {
      console.log(part.text);
    }
    if (part.inlineData) {
      finalImagePart = part;
    }
  }

  if (finalImagePart) {
    const buffer = Buffer.from(finalImagePart.inlineData.data, "base64");
    fs.writeFileSync("generated_image.png", buffer);
    console.log("Image saved to generated_image.png");
  }
  ```

  ```bash Shell theme={null}
  curl -s -X POST \
    "https://api.cometapi.com/v1beta/models/gemini-3.1-flash-image-preview:generateContent" \
    -H "Authorization: Bearer $COMETAPI_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "contents": [{
        "parts": [{"text": "Create a picture of a nano banana dish in a fancy restaurant with a Gemini theme"}]
      }],
      "generationConfig": {
        "responseModalities": ["TEXT", "IMAGE"]
      }
    }'
  ```
</CodeGroup>

**Salva la parte finale dell'immagine:**

I dati dell'immagine si trovano in `candidates[0].content.parts`, che può contenere parti di testo e/o immagini. I modelli di immagini Gemini possono anche restituire parti di ragionamento intermedie prima dell'immagine finale, soprattutto quando richiedi sia testo che immagini o abiliti esplicitamente l'output di thinking. Non salvare alla cieca il primo `inlineData`; salta le parti in cui `thought` è `true`, quindi salva l'ultima parte di immagine rimanente.

Risposta tipica con solo l'immagine finale:

```json theme={null}
{
  "candidates": [{
    "content": {
      "parts": [
        { "text": "Here is your image..." },
        {
          "inlineData": {
            "mimeType": "image/png",
            "data": "<base64-encoded-image>"
          }
        }
      ]
    }
  }]
}
```

Risposta con una parte di testo, un'immagine di ragionamento intermedia e l'immagine finale:

```json theme={null}
{
  "candidates": [{
    "content": {
      "role": "model",
      "parts": [
        { "text": "Here is your image..." },
        {
          "inlineData": {
            "mimeType": "image/jpeg",
            "data": "<base64-encoded-intermediate-image>"
          },
          "thought": true
        },
        {
          "inlineData": {
            "mimeType": "image/jpeg",
            "data": "<base64-encoded-final-image>"
          },
          "thought": false,
          "thoughtSignature": "<signature>"
        }
      ]
    },
    "finishReason": "STOP"
  }]
}
```

Usa questa regola di parsing per ogni risposta di immagini Gemini:

```javascript theme={null}
const imageParts = response.candidates[0].content.parts.filter(
  (part) => part.inlineData && part.thought !== true,
);
const finalImagePart = imageParts.at(-1);
```

***

## Generazione image-to-image

Carica un'immagine di input e trasformala con un prompt di testo.

<CodeGroup>
  ```python Python theme={null}
  from google import genai
  from google.genai import types
  from PIL import Image
  import os

  client = genai.Client(
      http_options={"api_version": "v1beta", "base_url": "https://api.cometapi.com"},
      api_key=os.environ.get("COMETAPI_KEY"),
  )

  # Load the source image
  source_image = Image.open("source.jpg")

  response = client.models.generate_content(
      model="gemini-3.1-flash-image-preview",
      contents=["Transform this into a watercolor painting", source_image],
      config=types.GenerateContentConfig(
          response_modalities=["TEXT", "IMAGE"],
      ),
  )

  final_image = None
  for part in response.parts:
      if getattr(part, "thought", False):
          continue
      if part.text is not None:
          print(part.text)
      elif part.inline_data is not None:
          final_image = part.as_image()

  if final_image:
      final_image.save("watercolor_output.png")
  ```

  ```javascript Node.js theme={null}
  import { GoogleGenAI } from "@google/genai";
  import * as fs from "fs";

  const ai = new GoogleGenAI({
    apiKey: process.env.COMETAPI_KEY,
    httpOptions: { apiVersion: "v1beta", baseUrl: "https://api.cometapi.com" },
  });

  const imageData = fs.readFileSync("source.jpg").toString("base64");

  const response = await ai.models.generateContent({
    model: "gemini-3.1-flash-image-preview",
    contents: [
      { text: "Transform this into a watercolor painting" },
      { inlineData: { mimeType: "image/jpeg", data: imageData } },
    ],
    config: { responseModalities: ["TEXT", "IMAGE"] },
  });

  const imageParts = response.candidates[0].content.parts.filter(
    (part) => part.inlineData && part.thought !== true,
  );
  const finalImagePart = imageParts.at(-1);

  if (finalImagePart) {
    fs.writeFileSync("watercolor_output.png", Buffer.from(finalImagePart.inlineData.data, "base64"));
  }
  ```

  ```bash Shell theme={null}
  curl -s -X POST \
    "https://api.cometapi.com/v1beta/models/gemini-3.1-flash-image-preview:generateContent" \
    -H "Authorization: Bearer $COMETAPI_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "contents": [{
        "role": "user",
        "parts": [
          { "text": "Transform this into a watercolor painting" },
          { "inline_data": { "mime_type": "image/jpeg", "data": "<base64-encoded-source-image>" } }
        ]
      }],
      "generationConfig": { "responseModalities": ["TEXT", "IMAGE"] }
    }'
  ```
</CodeGroup>

<Note>
  * L'SDK Python accetta direttamente oggetti `PIL.Image` — non è necessaria alcuna codifica Base64 manuale.
  * **Non** includere il prefisso `data:image/jpeg;base64,` quando passi stringhe Base64 raw.
</Note>

***

## Composizione multi-immagine

Genera una nuova immagine a partire da più immagini di input. CometAPI supporta due approcci:

### Metodo 1: Una singola immagine collage

Combina più immagini sorgente in un unico collage, quindi descrivi l'output desiderato.

<Frame>
  <img src="https://mintcdn.com/cometapi/OukMcVwzR05umRJn/images/image/gemini/6100640_569419.png?fit=max&auto=format&n=OukMcVwzR05umRJn&q=85&s=02d820e809bd8e21e3b7b0c58592c6ab" alt="Esempio di collage di input" width="1200" height="754" data-path="images/image/gemini/6100640_569419.png" />
</Frame>

<Frame>
  <img src="https://mintcdn.com/cometapi/OukMcVwzR05umRJn/images/image/gemini/6100640_569420.png?fit=max&auto=format&n=OukMcVwzR05umRJn&q=85&s=b8f128a921f62619b575926da824fd43" alt="Output generato" width="1200" height="733" data-path="images/image/gemini/6100640_569420.png" />
</Frame>

<CodeGroup>
  ```python Python theme={null}
  from google import genai
  from google.genai import types
  from PIL import Image
  import os

  client = genai.Client(
      http_options={"api_version": "v1beta", "base_url": "https://api.cometapi.com"},
      api_key=os.environ.get("COMETAPI_KEY"),
  )

  collage = Image.open("collage.jpg")

  response = client.models.generate_content(
      model="gemini-3.1-flash-image-preview",
      contents=[
          "A model is posing and leaning against a pink BMW with a green alien keychain attached to a pink handbag, a pink parrot on her shoulder, and a pug wearing a pink collar and gold headphones",
          collage,
      ],
      config=types.GenerateContentConfig(
          response_modalities=["TEXT", "IMAGE"],
      ),
  )

  final_image = None
  for part in response.parts:
      if getattr(part, "thought", False):
          continue
      if part.inline_data is not None:
          final_image = part.as_image()

  if final_image:
      final_image.save("composition_output.png")
  ```

  ```bash Shell theme={null}
  curl -s -X POST \
    "https://api.cometapi.com/v1beta/models/gemini-3.1-flash-image-preview:generateContent" \
    -H "Authorization: Bearer $COMETAPI_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "contents": [{
        "role": "user",
        "parts": [
          { "text": "A model is posing and leaning against a pink BMW with a green alien keychain attached to a pink handbag, a pink parrot on her shoulder, and a pug wearing a pink collar and gold headphones" },
          { "inline_data": { "mime_type": "image/jpeg", "data": "<base64-encoded-collage-image>" } }
        ]
      }],
      "generationConfig": { "responseModalities": ["TEXT", "IMAGE"] }
    }'
  ```
</CodeGroup>

### Metodo 2: Più immagini separate (fino a 14)

Passa più immagini direttamente. I modelli Gemini 3 supportano fino a 14 immagini di riferimento (oggetti + personaggi):

<CodeGroup>
  ```python Python theme={null}
  from google import genai
  from google.genai import types
  from PIL import Image
  import os

  client = genai.Client(
      http_options={"api_version": "v1beta", "base_url": "https://api.cometapi.com"},
      api_key=os.environ.get("COMETAPI_KEY"),
  )

  image1 = Image.open("image1.jpg")
  image2 = Image.open("image2.jpg")
  image3 = Image.open("image3.jpg")

  response = client.models.generate_content(
      model="gemini-3.1-flash-image-preview",
      contents=["Merge the three images", image1, image2, image3],
      config=types.GenerateContentConfig(
          response_modalities=["TEXT", "IMAGE"],
      ),
  )

  final_image = None
  for part in response.parts:
      if getattr(part, "thought", False):
          continue
      if part.inline_data is not None:
          final_image = part.as_image()

  if final_image:
      final_image.save("merged_output.png")
  ```

  ```bash Shell theme={null}
  curl -s -X POST \
    "https://api.cometapi.com/v1beta/models/gemini-3.1-flash-image-preview:generateContent" \
    -H "Authorization: Bearer $COMETAPI_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "contents": [{
        "role": "user",
        "parts": [
          { "text": "Merge the three images" },
          { "inline_data": { "mime_type": "image/jpeg", "data": "<base64-image-1>" } },
          { "inline_data": { "mime_type": "image/jpeg", "data": "<base64-image-2>" } },
          { "inline_data": { "mime_type": "image/jpeg", "data": "<base64-image-3>" } }
        ]
      }],
      "generationConfig": { "responseModalities": ["TEXT", "IMAGE"] }
    }'
  ```
</CodeGroup>

<Frame>
  <img src="https://mintcdn.com/cometapi/OukMcVwzR05umRJn/images/image/gemini/6100640_569429.png?fit=max&auto=format&n=OukMcVwzR05umRJn&q=85&s=2a1ea93ce3477491d8014283896c31e2" alt="Risultato della generazione multi-immagine" width="1248" height="832" data-path="images/image/gemini/6100640_569429.png" />
</Frame>

***

## Generazione di immagini 4K

Specifica `image_config` con `aspect_ratio` e `image_size` per un output ad alta risoluzione:

<CodeGroup>
  ```python Python theme={null}
  from google import genai
  from google.genai import types
  import os

  client = genai.Client(
      http_options={"api_version": "v1beta", "base_url": "https://api.cometapi.com"},
      api_key=os.environ.get("COMETAPI_KEY"),
  )

  response = client.models.generate_content(
      model="gemini-3.1-flash-image-preview",
      contents="Da Vinci style anatomical sketch of a Monarch butterfly on textured parchment",
      config=types.GenerateContentConfig(
          response_modalities=["TEXT", "IMAGE"],
          image_config=types.ImageConfig(
              aspect_ratio="1:1",
              image_size="4K",
          ),
      ),
  )

  final_image = None
  for part in response.parts:
      if getattr(part, "thought", False):
          continue
      if part.text is not None:
          print(part.text)
      elif image := part.as_image():
          final_image = image

  if final_image:
      final_image.save("butterfly_4k.png")
  ```

  ```javascript Node.js theme={null}
  import { GoogleGenAI } from "@google/genai";
  import * as fs from "fs";

  const ai = new GoogleGenAI({
    apiKey: process.env.COMETAPI_KEY,
    httpOptions: { apiVersion: "v1beta", baseUrl: "https://api.cometapi.com" },
  });

  const response = await ai.models.generateContent({
    model: "gemini-3.1-flash-image-preview",
    contents: "Da Vinci style anatomical sketch of a Monarch butterfly on textured parchment",
    config: {
      responseModalities: ["TEXT", "IMAGE"],
      imageConfig: { aspectRatio: "1:1", imageSize: "4K" },
    },
  });

  const imageParts = response.candidates[0].content.parts.filter(
    (part) => part.inlineData && part.thought !== true,
  );
  const finalImagePart = imageParts.at(-1);

  if (finalImagePart) {
    fs.writeFileSync("butterfly_4k.png", Buffer.from(finalImagePart.inlineData.data, "base64"));
  }
  ```

  ```bash Shell theme={null}
  curl -s -X POST \
    "https://api.cometapi.com/v1beta/models/gemini-3.1-flash-image-preview:generateContent" \
    -H "Authorization: Bearer $COMETAPI_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "contents": [{"parts": [{"text": "Da Vinci style anatomical sketch of a Monarch butterfly on textured parchment"}]}],
      "generationConfig": {
        "responseModalities": ["TEXT", "IMAGE"],
        "imageConfig": {"aspectRatio": "1:1", "imageSize": "4K"}
      }
    }'
  ```
</CodeGroup>

<Note>
  Per le richieste ad alta risoluzione, valuta l'output in base alla parte finale dell'immagine non-thought. Se la tua integrazione salva la prima parte `inlineData`, potrebbe salvare un'immagine thought intermedia con una risoluzione inferiore rispetto a `imageSize` richiesto.
</Note>

***

## Modifica iterativa delle immagini (chat)

Usa la funzionalità chat dell'SDK per perfezionare iterativamente le immagini:

<CodeGroup>
  ```python Python theme={null}
  from google import genai
  from google.genai import types
  import os

  client = genai.Client(
      http_options={"api_version": "v1beta", "base_url": "https://api.cometapi.com"},
      api_key=os.environ.get("COMETAPI_KEY"),
  )

  chat = client.chats.create(
      model="gemini-3.1-flash-image-preview",
      config=types.GenerateContentConfig(
          response_modalities=["TEXT", "IMAGE"],
      ),
  )

  ## First turn: Generate
  response = chat.send_message(
      "Create a vibrant infographic explaining photosynthesis as a recipe, styled like a colorful kids cookbook"
  )

  final_image = None
  for part in response.parts:
      if getattr(part, "thought", False):
          continue
      if part.text is not None:
          print(part.text)
      elif image := part.as_image():
          final_image = image

  if final_image:
      final_image.save("photosynthesis.png")
  ```

  ## Secondo turno: rifinisci

  response = chat.send\_message("Aggiorna questa infografica affinché sia in spagnolo. Non modificare nessun altro elemento.")

  final\_image = None
  for part in response.parts:
  if getattr(part, "thought", False):
  continue
  if part.text is not None:
  print(part.text)
  elif image := part.as\_image():
  final\_image = image

  if final\_image:
  final\_image.save("photosynthesis\_spanish.png")

  ````

  ```javascript Node.js
  import { GoogleGenAI } from "@google/genai";
  import * as fs from "fs";

  const ai = new GoogleGenAI({
    apiKey: process.env.COMETAPI_KEY,
    httpOptions: { apiVersion: "v1beta", baseUrl: "https://api.cometapi.com" },
  });

  const chat = ai.chats.create({
    model: "gemini-3.1-flash-image-preview",
    config: { responseModalities: ["TEXT", "IMAGE"] },
  });

  // First turn: generate
  const response1 = await chat.sendMessage(
    "Create a vibrant infographic explaining photosynthesis as a recipe, styled like a colorful kids cookbook"
  );
  const imageParts1 = response1.candidates[0].content.parts.filter(
    (part) => part.inlineData && part.thought !== true,
  );
  const finalImagePart1 = imageParts1.at(-1);
  if (finalImagePart1) {
    fs.writeFileSync("photosynthesis.png", Buffer.from(finalImagePart1.inlineData.data, "base64"));
  }

  // Second turn: refine
  const response2 = await chat.sendMessage(
    "Update this infographic to be in Spanish. Do not change any other elements."
  );
  const imageParts2 = response2.candidates[0].content.parts.filter(
    (part) => part.inlineData && part.thought !== true,
  );
  const finalImagePart2 = imageParts2.at(-1);
  if (finalImagePart2) {
    fs.writeFileSync("photosynthesis_spanish.png", Buffer.from(finalImagePart2.inlineData.data, "base64"));
  }
  ````
</CodeGroup>

***

## Suggerimenti

<AccordionGroup>
  <Accordion title="Ottimizzazione del Prompt">
    Specifica parole chiave di stile (ad esempio, "cyberpunk, grana della pellicola, basso contrasto"), aspect ratio, soggetto, sfondo, illuminazione e livello di dettaglio.
  </Accordion>

  <Accordion title="Formato Base64">
    Quando usi HTTP raw, non includere il prefisso `data:image/png;base64,` — usa solo la stringa Base64 raw. Il Python SDK gestisce questo automaticamente con oggetti `PIL.Image`.
  </Accordion>

  <Accordion title="Forzare l'output immagine">
    Imposta `"responseModalities"` solo su `["IMAGE"]` per garantire un output immagine senza testo.
  </Accordion>

  <Accordion title="Perché la mia immagine è sfocata o ha una risoluzione più bassa?">
    Controlla se il tuo codice ha salvato un'immagine di thought intermedia. Le risposte immagine di Gemini possono includere parti immagine in cui `thought` è `true`; queste non sono l'output finale. Salta le parti `thought: true` e salva l'ultima parte immagine in cui `inlineData` esiste e `thought` non è `true`. Se non ti serve l'output di testo, richiedi `"responseModalities": ["IMAGE"]` per ridurre la gestione di risposte miste testo/immagine.
  </Accordion>
</AccordionGroup>

Per maggiori dettagli, vedi la [API Reference](/api/image/gemini/gemini-generates-image).

**Documentazione ufficiale:** [Generazione di immagini Nano Banana](https://ai.google.dev/gemini-api/docs/image-generation)

* [Gemini Image Understanding](https://ai.google.dev/gemini-api/docs/image-understanding)
