> ## 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 image API 빠른 시작: CometAPI로 Nano Banana 이미지 생성하기

> CometAPI를 통해 Gemini 이미지 모델( Nano Banana 모델 계열 포함)로 이미지를 생성하고, curl, Python, 또는 Node.js로 `inlineData` 출력을 저장합니다.

## 만들게 될 것

CometAPI를 통해 Gemini 이미지 `generateContent` 라우트를 호출하고, Nano Banana 모델 계열을 포함한 Gemini 이미지 모델에서 이미지 출력을 요청하며, 중간 `thought` 이미지 파트를 건너뛰고, 최종 `inlineData` 이미지를 저장하게 됩니다.

## 사전 준비 사항

* `COMETAPI_KEY`에 저장된 CometAPI API 키
* `requests`가 설치된 Python 3.10+ 또는 Node.js 18+
* Gemini 이미지 model ID. 유지 관리되는 API 레퍼런스에서는 텍스트-투-이미지 예제로 `gemini-3.1-flash-image-preview`를 사용합니다.

## API 키, 기본 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`인 중간 이미지 파트가 포함될 수 있습니다.

결과를 저장할 때는 이미지 파트를 순회하면서 `thought: true`를 무시하고, 마지막으로 남는 `inlineData` 이미지를 저장하세요.

## 공통 파라미터

| Parameter                             | Use                                                 |
| ------------------------------------- | --------------------------------------------------- |
| `model` path segment                  | URL 경로의 Gemini 이미지 model ID                         |
| `contents`                            | 프롬프트(Prompt)와 선택적 입력 이미지 파트                         |
| `generationConfig.responseModalities` | 이미지 출력이 필요할 때 `IMAGE`를 포함합니다.                       |
| `generationConfig.imageConfig`        | 선택한 모델이 지원하는 경우 화면비와 이미지 크기 같은 이미지 옵션               |
| `tools`                               | 선택적 Gemini 도구. API 레퍼런스에 선택한 워크플로가 문서화된 경우에만 추가하세요. |

## 문제 해결 / FAQ

<AccordionGroup>
  <Accordion title="응답에 thought 이미지가 포함됩니다">
    `thought`가 `true`인 파트는 저장하지 마세요. 이것들은 최종 출력이 아닌 중간 이미지입니다.
  </Accordion>

  <Accordion title="요청이 텍스트만 반환합니다">
    `generationConfig.responseModalities`에 `IMAGE`가 포함되어 있는지, 그리고 선택한 모델이 이미지 출력을 지원하는지 확인하세요.
  </Accordion>

  <Accordion title="이미지-투-이미지가 필요합니다">
    Gemini 이미지 가이드에 나온 것처럼 `inline_data` 요청 파트를 사용하고, 최종 이미지 파싱 로직은 동일하게 유지하세요.
  </Accordion>
</AccordionGroup>

## 다음 단계

* [Gemini image API 레퍼런스](/api/image/gemini/gemini-generates-image)를 읽어보세요.
* [Gemini 이미지 모델 사용하기](/api/image/gemini/generate-image-guide)에서 더 많은 예제를 확인하세요.
* [Models](/ko/overview/models)에서 사용 가능한 이미지 모델을 찾아보세요.
* [모델 호출 전에 요청 비용 추정하기](/ko/guides/how-to-estimate-cost-before-calling-a-model)로 비용을 예측하세요.
