> ## 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
* 安装了 `requests` 的 Python 3.10+，或 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                             | Use                                     |
| ------------------------------------- | --------------------------------------- |
| `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="我需要图生图">
    按照 Gemini 图像指南中的说明使用 `inline_data` 请求 parts，并保持最终图像解析逻辑不变。
  </Accordion>
</AccordionGroup>

## 后续步骤

* 阅读 [Gemini 图像 API 参考](/api/image/gemini/gemini-generates-image)。
* 在[使用 Gemini 图像模型](/api/image/gemini/generate-image-guide)中查看更多示例。
* 在 [Models](/zh-Hans/overview/models) 中查找可用的图像模型。
* 使用[在调用模型前估算请求成本](/zh-Hans/guides/how-to-estimate-cost-before-calling-a-model)估算成本。
