> ## 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.

# Gemini 圖像 API 快速入門：使用 CometAPI 產生 Nano Banana 圖像

> 透過 CometAPI 使用 Gemini 圖像模型產生圖片，包括 Nano Banana 模型系列，並使用 curl、Python 或 Node.js 儲存 inlineData 輸出。

## 你將建立的內容

你將透過 CometAPI 呼叫 Gemini 圖像的 `generateContent` 路由，向 Gemini 圖像模型（包括 Nano Banana 模型系列）請求圖像輸出，略過中間的 `thought` 圖像部分，並儲存最終的 `inlineData` 圖像。

## 先決條件

* 已儲存在 `COMETAPI_KEY` 中的 CometAPI API key
* Python 3.10+ 與 `requests`，或 Node.js 18+
* 一個 Gemini 圖像 model ID。維護中的 API 參考使用 `gemini-3.1-flash-image-preview` 作為文字轉圖片範例。

## API key、基礎 URL、驗證

透過 CometAPI 使用 Gemini 圖像路由：

```text theme={null}
https://api.cometapi.com/v1beta/models/gemini-3.1-flash-image-preview:generateContent
```

使用 `x-goog-api-key` 進行驗證：

```text theme={null}
x-goog-api-key: $COMETAPI_KEY
```

## 程式碼範例

使用下方分頁查看可直接複製的 cURL、Python 與 Node.js 範例。

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

  ```python Python theme={null}
  import base64
  import os
  import requests

  response = requests.post(
      "https://api.cometapi.com/v1beta/models/gemini-3.1-flash-image-preview:generateContent",
      headers={
          "x-goog-api-key": os.environ["COMETAPI_KEY"],
          "Content-Type": "application/json",
      },
      json={
          "contents": [
              {
                  "parts": [
                      {
                          "text": "A Monarch butterfly anatomical sketch on textured parchment"
                      }
                  ]
              }
          ],
          "generationConfig": {
              "responseModalities": ["TEXT", "IMAGE"],
              "imageConfig": {"aspectRatio": "1:1", "imageSize": "4K"},
          },
      },
      timeout=120,
  )
  response.raise_for_status()

  parts = response.json()["candidates"][0]["content"]["parts"]
  for part in reversed(parts):
      if part.get("thought") is True:
          continue
      inline_data = part.get("inlineData")
      if inline_data:
          image_bytes = base64.b64decode(inline_data["data"])
          mime_type = inline_data.get("mimeType", "image/png")
          extension = "jpg" if mime_type == "image/jpeg" else "png"
          with open(f"nano-banana-result.{extension}", "wb") as file:
              file.write(image_bytes)
          break
  else:
      raise RuntimeError("No final image part found")
  ```

  ```javascript Node.js theme={null}
  import fs from "node:fs/promises";

  const response = await fetch(
    "https://api.cometapi.com/v1beta/models/gemini-3.1-flash-image-preview:generateContent",
    {
      method: "POST",
      headers: {
        "x-goog-api-key": process.env.COMETAPI_KEY,
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        contents: [
          {
            parts: [
              {
                text: "A Monarch butterfly anatomical sketch on textured parchment",
              },
            ],
          },
        ],
        generationConfig: {
          responseModalities: ["TEXT", "IMAGE"],
          imageConfig: { aspectRatio: "1:1", imageSize: "4K" },
        },
      }),
    },
  );

  if (!response.ok) {
    throw new Error(await response.text());
  }

  const body = await response.json();
  const parts = body.candidates[0].content.parts;
  const finalImage = [...parts]
    .reverse()
    .find((part) => part.thought !== true && part.inlineData);

  if (!finalImage) {
    throw new Error("No final image part found");
  }

  const mimeType = finalImage.inlineData.mimeType || "image/png";
  const extension = mimeType === "image/jpeg" ? "jpg" : "png";
  await fs.writeFile(
    `nano-banana-result.${extension}`,
    Buffer.from(finalImage.inlineData.data, "base64"),
  );
  ```
</CodeGroup>

## 流程說明

Gemini 圖像生成在這個路由上是同步的。回應使用 Gemini 原生的 `candidates[].content.parts[]`。parts 可能包含文字、生成的圖像，以及 `thought` 為 `true` 的中間圖像部分。

儲存結果時，請逐一處理圖像 parts、忽略 `thought: true`，並儲存最後剩下的 `inlineData` 圖像。

## 常見參數

| Parameter                             | 用途                                       |
| ------------------------------------- | ---------------------------------------- |
| `model` path segment                  | URL 路徑中的 Gemini 圖像 model ID。             |
| `contents`                            | Prompt 與可選的輸入圖像 parts。                   |
| `generationConfig.responseModalities` | 當你需要圖像輸出時，包含 `IMAGE`。                    |
| `generationConfig.imageConfig`        | 選定模型支援時的圖像選項，例如長寬比與圖像尺寸。                 |
| `tools`                               | 可選的 Gemini tools。僅在 API 參考文件記載所選工作流程時加入。 |

## 疑難排解 / 常見問答

<AccordionGroup>
  <Accordion title="回應中包含 thought 圖像">
    不要儲存 `thought` 為 `true` 的 parts。這些是中間圖像，不是最終輸出。
  </Accordion>

  <Accordion title="請求只回傳文字">
    請檢查 `generationConfig.responseModalities` 是否包含 `IMAGE`，以及所選模型是否支援圖像輸出。
  </Accordion>

  <Accordion title="我需要 image-to-image">
    依照 Gemini 圖像指南所示使用 `inline_data` 請求 parts，並保持最終圖像的解析邏輯不變。
  </Accordion>
</AccordionGroup>

## 後續步驟

* 閱讀 [Gemini 圖像 API 參考](/api/image/gemini/gemini-generates-image)。
* 在 [使用 Gemini 圖像模型](/api/image/gemini/generate-image-guide) 查看更多範例。
* 在 [Models](/zh-Hant/overview/models) 中尋找可用的圖像模型。
* 使用 [在呼叫模型前估算請求成本](/zh-Hant/guides/how-to-estimate-cost-before-calling-a-model) 估算成本。
