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

# 图像生成：Gemini Image 与 GPT Image

> 用 RuAPI 生成和编辑图片：Nano Banana（Gemini 2.5/3 Image）走聊天端点，GPT Image 走 /v1/images/generations —— curl / Python 示例

RuAPI 提供两个系列的图像生成模型：**Gemini Image**（也就是俗称的 Nano Banana）和 **GPT Image**。它们的**调用方式完全不同**，这是动手之前必须先搞清楚的一点。USDT 计费，无需外币卡。

<Warning>
  **Gemini 图像模型不走 `/v1/images/generations`。** 它们走普通的聊天端点 `/v1/chat/completions`，生成的图片直接夹在回复正文里。详见「方式一」。
</Warning>

## 可用模型

| 模型 ID                            | 端点                       | 计费方式    | 什么时候用                 |
| -------------------------------- | ------------------------ | ------- | --------------------- |
| `gemini-2.5-flash-image`         | chat                     | 按次      | 最便宜。改图能力尤其强           |
| `gemini-3.1-flash-image-preview` | chat                     | 按次      | 更快，画质好于 2.5           |
| `gemini-3-pro-image-preview`     | chat                     | 按次      | 画质最高（Nano Banana Pro） |
| `gpt-image-2`                    | `/v1/images/generations` | 按 token | 兼容 OpenAI 生态          |

准确的价格见主站 **[价格页面](https://www.ruapi.ai/pricing)**。Gemini 系列**按次计费**（一张图一口价），`gpt-image-2` **按 token 计费**（图越大、质量越高越贵）。

## 接口地址与鉴权

* **Base URL**：`https://www.ruapi.ai/v1`
* **鉴权**：请求头带 `Authorization: Bearer sk-你的KEY`（在控制台「令牌」页创建）

***

## 方式一：Gemini Image —— 走聊天端点

Gemini 图像模型挂在**聊天端点**上。你像调文本模型一样发请求，回来的是图片。

<Warning>
  **图片是以 Markdown data URI 的形式内联在 `choices[0].message.content` 里的** —— 没有单独的图片字段。响应长这样：

  ```
  这是一只穿着宇航服、以土星为背景的橘猫！
  ![image](data:image/png;base64,iVBORw0KGgoAAAANSUhEUg...)
  ```

  你得自己把 base64 从正文里抠出来。下面是现成的代码。
</Warning>

### 文生图

<CodeGroup>
  ```bash curl theme={null}
  curl https://www.ruapi.ai/v1/chat/completions \
    -H "Authorization: Bearer sk-你的KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "model": "gemini-2.5-flash-image",
      "messages": [
        { "role": "user", "content": "画一只穿着宇航服、以土星为背景的橘猫" }
      ]
    }'
  ```

  ```python Python (requests) theme={null}
  import base64
  import re

  import requests

  resp = requests.post(
      "https://www.ruapi.ai/v1/chat/completions",
      headers={"Authorization": "Bearer sk-你的KEY"},
      json={
          "model": "gemini-2.5-flash-image",
          "messages": [
              {"role": "user", "content": "画一只穿着宇航服、以土星为背景的橘猫"}
          ],
      },
  )
  content = resp.json()["choices"][0]["message"]["content"]

  # 把所有 Markdown data URI 里的图片抠出来
  images = re.findall(r"!\[image\]\(data:(image/[^;]+);base64,([^)]+)\)", content)
  for i, (mime, b64) in enumerate(images):
      ext = mime.split("/")[-1]
      with open(f"image_{i}.{ext}", "wb") as f:
          f.write(base64.b64decode(b64))

  # 模型在图片旁边写的那句话
  caption = re.sub(r"!\[image\]\([^)]*\)", "", content).strip()
  print(caption, f"—— 共保存 {len(images)} 张图")
  ```
</CodeGroup>

<Tip>
  一次响应里可能有**多张**图，所以例子里用的是 `findall` 而不是 `search`。模型几乎总会在图片旁边附一句简短的文字说明。
</Tip>

### 图生图（编辑）

要改一张已有的图，按 vision 模型的格式传进去即可：`content` 用数组，里面放 `text` 和 `image_url` 两部分。`url` 既可以是公网链接，也可以是 data URI。

<CodeGroup>
  ```bash curl theme={null}
  curl https://www.ruapi.ai/v1/chat/completions \
    -H "Authorization: Bearer sk-你的KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "model": "gemini-2.5-flash-image",
      "messages": [
        {
          "role": "user",
          "content": [
            { "type": "text", "text": "把这张图改成黑白的，其他什么都别动。" },
            { "type": "image_url", "image_url": { "url": "https://example.com/photo.jpg" } }
          ]
        }
      ]
    }'
  ```

  ```python Python (requests) theme={null}
  import base64
  import re
  from pathlib import Path

  import requests

  # 方案 A —— 公网图片链接
  source = {"url": "https://example.com/photo.jpg"}

  # 方案 B —— 本地文件走 data URI
  # raw = Path("photo.jpg").read_bytes()
  # source = {"url": "data:image/jpeg;base64," + base64.b64encode(raw).decode()}

  resp = requests.post(
      "https://www.ruapi.ai/v1/chat/completions",
      headers={"Authorization": "Bearer sk-你的KEY"},
      json={
          "model": "gemini-2.5-flash-image",
          "messages": [
              {
                  "role": "user",
                  "content": [
                      {"type": "text", "text": "把这张图改成黑白的，其他什么都别动。"},
                      {"type": "image_url", "image_url": source},
                  ],
              }
          ],
      },
  )
  content = resp.json()["choices"][0]["message"]["content"]
  mime, b64 = re.findall(r"!\[image\]\(data:(image/[^;]+);base64,([^)]+)\)", content)[0]
  Path("edited.png").write_bytes(base64.b64decode(b64))
  ```
</CodeGroup>

<Note>
  输入图的宽高比会被保留，结果不会被裁成正方形。
</Note>

### 多轮连续修图

模型的回复可以**原样塞回** `messages` 里当作 `assistant` 消息 —— 其中的 Markdown data URI 会被识别，图片将作为下一轮的输入。这样就能做「改成黑白」→「再加个白边」这种连续编辑。

```python theme={null}
messages = [{"role": "user", "content": "画一只橘猫"}]

for instruction in ["把图片改成黑白的", "加一圈白色边框"]:
    resp = requests.post(URL, headers=HEADERS, json={"model": MODEL, "messages": messages}).json()
    reply = resp["choices"][0]["message"]["content"]
    messages.append({"role": "assistant", "content": reply})   # 图片留在上下文里
    messages.append({"role": "user", "content": instruction})
```

<Warning>
  每一轮都是**一次独立的付费调用**。另外，带 base64 图片的历史会让请求体迅速膨胀，别把超过两三张的历史图都塞进上下文。
</Warning>

### 支持的输入图片格式

`image/png`、`image/jpeg`、`image/webp`、`image/heic`、`image/heif`。其他格式会被拒绝，报 `mime type is not supported by Gemini`。

### 原生 Gemini 端点

如果你本来就在用 Google GenAI SDK，同一个密钥也能走原生格式：

```bash theme={null}
curl "https://www.ruapi.ai/v1beta/models/gemini-2.5-flash-image:generateContent" \
  -H "Authorization: Bearer sk-你的KEY" \
  -H "Content-Type: application/json" \
  -d '{ "contents": [{ "parts": [{ "text": "画一只穿着宇航服的橘猫" }] }] }'
```

这条路径下图片是**结构化返回**的 —— 在 `candidates[0].content.parts[].inlineData.data`（base64），不用解析 Markdown。如果你不需要兼容 OpenAI SDK，这个方式更省事。

***

## 方式二：GPT Image —— 走 `/v1/images/generations`

`gpt-image-2` 就是 OpenAI 那套经典的图像生成端点。没有 `messages`，只有 `prompt`。

<CodeGroup>
  ```bash curl theme={null}
  curl https://www.ruapi.ai/v1/images/generations \
    -H "Authorization: Bearer sk-你的KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "model": "gpt-image-2",
      "prompt": "一只穿着宇航服、以土星为背景的橘猫",
      "size": "1024x1024",
      "quality": "low",
      "n": 1
    }'
  ```

  ```python Python (openai SDK) theme={null}
  import base64

  from openai import OpenAI

  client = OpenAI(api_key="sk-你的KEY", base_url="https://www.ruapi.ai/v1")

  result = client.images.generate(
      model="gpt-image-2",
      prompt="一只穿着宇航服、以土星为背景的橘猫",
      size="1024x1024",
      quality="low",
      n=1,
  )

  with open("image.png", "wb") as f:
      f.write(base64.b64decode(result.data[0].b64_json))
  ```
</CodeGroup>

### 参数

| 参数        | 取值                                   | 说明                         |
| --------- | ------------------------------------ | -------------------------- |
| `size`    | `1024x1024`、`1536x1024`、`1024x1536`… | 两边长度都必须是 **16 的倍数**        |
| `quality` | `low`、`medium`、`high`                | 决定输出 token 数，也就是**直接决定价格** |
| `n`       | 1 或更多                                | 每张图单独计费                    |

### 响应

```json theme={null}
{
  "data": [
    {
      "b64_json": "iVBORw0KGgoAAAANSUhEUg...",
      "url": "https://.../image.png",
      "revised_prompt": "一只穿着宇航服、以土星为背景的橘猫"
    }
  ],
  "usage": { "input_tokens": 17, "output_tokens": 425, "total_tokens": 442 }
}
```

<Warning>
  **请用 `b64_json`，不要用 `url`。** `url` 指向的是外部存储，链接有效期没有保证，随时可能打不开。`b64_json` 就是图片本身，拿到手就永久属于你。
</Warning>

<Tip>
  `usage.output_tokens` 是图片 token，价格就按它算。把 `quality` 降到 `low` 能让它成倍减少，适合出草稿和做测试。
</Tip>

***

## 常见问题

<AccordionGroup>
  <Accordion title="为什么 gemini-2.5-flash-image 走 /v1/images/generations 不通？">
    因为按 OpenAI 的口径它不是「图像生成模型」，而是一个能吐图片的多模态聊天模型。请用 `/v1/chat/completions` 调用，见「方式一」。
  </Accordion>

  <Accordion title="content 里那一大坨 base64 是什么？">
    那就是图片。通过 OpenAI 兼容的聊天端点返回时，图片被拼成 `![image](data:image/png;base64,...)` 塞进正文。用上面的正则抠出来即可；或者改走原生 Gemini 端点，那里图片是独立字段。
  </Accordion>

  <Accordion title="修图该选哪个模型？">
    `gemini-2.5-flash-image` 性价比最高。要极致细节就用 `gemini-3-pro-image-preview`。`gpt-image-2` 也能改图，但走的是另一个端点 `/v1/images/edits`。
  </Accordion>

  <Accordion title="生成结果能保存多久？">
    Gemini 系列什么都不存，base64 直接在响应里。`gpt-image-2` 的响应带一个 `url` 字段，但不要依赖它 —— 把 `b64_json` 存下来。
  </Accordion>

  <Accordion title="Gemini 的响应里有 usage 和 token 数，会按这个扣费吗？">
    不会。Gemini 图像模型**按次计费**，一张图一口价。`usage` 只是参考信息，不参与扣费。只有 `gpt-image-2` 是按 token 计费的。
  </Accordion>
</AccordionGroup>
