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

# Nano Banana APIの画像編集：Standardの使い方

> gemini-2.5-flash-imageで画像を編集・合成する手順です。Googleの提供終了日を過ぎてもLaoZhang APIでは引き続き使えます。Nano Banana 2への移行方法もまとめています。

> [!WARNING]
>
> **`gemini-2.5-flash-image` はGoogleの提供終了日を過ぎています。LaoZhang APIでは現在も使えますが、いつ停止してもおかしくないため、早めに移行してください。**
>
> * Googleの日付は食い違っています。2026年10月8日時点で、[非推奨モデルのページ](https://ai.google.dev/gemini-api/docs/deprecations)は2027年3月15日としていますが、料金のページはまだ2026年10月2日と警告しています。2026年10月5日時点で、LaoZhang APIの料金は変わらず1回\$0.02で、終了日の保証はありません。
> * 編集はNano Banana 2（`gemini-3.1-flash-image`）か、1回\$0.045とより低い料金のNano Banana 2.1（`gemini-nano-banana-2.1`）に移してください。どちらも同じリクエストを受け付けるので、変えるのはモデルIDだけです。手順は後述の「Nano Banana 2に移行する」にあります。

Nano Banana Standard（`gemini-2.5-flash-image`）は、テキストの指示で画像を編集し、最大3枚の画像を1枚に合成できます。このページでは、編集リクエストの送り方、結果の保存、Nano Banana 2への移行を説明します。

| 項目 | 内容 |
| - | - |
| モデルID | `gemini-2.5-flash-image` |
| 編集の種類 | オブジェクトの追加・削除、背景の差し替え、写真のスタイル変更、最大3枚の合成 |
| エンドポイント | `https://api.laozhang.ai` のOpenAI互換 `POST /v1/chat/completions`。アスペクト比を指定したい場合はGeminiネイティブの `generateContent` |
| 入力 | 1つの指示と、PNG、JPEG、WebPの画像1〜3枚を1回のリクエストで送る |
| 出力 | 約1Kの画像1枚。Base64で返るので、デコードして保存する |
| アスペクト比 | 10種。Geminiネイティブのルートのみ |
| マスク | なし。変えたい範囲は指示の中で説明する |
| 料金 | 1回\$0.02（2026年9月24日時点の公開価格。[AIモデルのAPI料金一覧](https://docs.laozhang.ai/ja/models.md)を参照） |
| 課金 | HTTP 200の応答は、画像がなくても1回分が課金されます。詳しくは[Nano Bananaの概要](https://docs.laozhang.ai/ja/api-capabilities/nano-banana-image.md)の「課金」 |

Standardは最初のNano Bananaモデルで、このサイトではモデルファミリーと区別するためにStandardと呼んでいます。Nano Banana 2 Lite、Nano Banana 2、Nano Banana Proとの比較は、[Nano Bananaの概要](https://docs.laozhang.ai/ja/api-capabilities/nano-banana-image.md)を参照してください。

## 始める前に

**1. APIキーを作成する**

[トークン管理](https://api.laozhang.ai/token)でトークン作成のダイアログ（创建令牌）を開き、**課金方式**（计费模式）を**従量優先**（按量优先、推奨）または**回数課金**（按次计费）にして、**作成**（创建）をクリックします。

Nano Bananaのモデルには回数課金の料金しかありません。従量優先のキーは、これらのモデルも従量課金のモデルも呼び出せますが、回数課金のキーが呼び出せるのは回数課金のモデルだけです。`default` グループには `gemini-2.5-flash-image` が含まれています。

![LaoZhang APIコンソールのトークン作成ダイアログ。課金方式で回数課金（按次计费）を選んでいる](https://mintcdn.com/laozhangai-edd05f2c/_loZ0Jy0ZI__xJ9z/images/token-create-per-request.png?fit=max\&auto=format\&n=_loZ0Jy0ZI__xJ9z\&q=85\&s=1fdceb804bb3ad50f83a21ec65b4d807)

**2. キーを設定し、依存パッケージをインストールする**

```bash theme={null}
export LAOZHANG_API_KEY="sk-..."  # 自分のLaoZhang APIキーに置き換える
python -m pip install openai requests
```

cURLの例には `jq` も必要です。たとえば `brew install jq` や `sudo apt-get install jq` でインストールします。

**3. レスポンスの保存ヘルパーを用意する**

次のモジュールを `nano_banana_save.py` として保存します。Pythonの例はこれをインポートし、cURLの場合は保存したレスポンスに対して実行します。chat completionsと `generateContent` のどちらのレスポンスからもすべての画像を見つけ、欠けたBase64のパディングを補い、実際の形式に合わせてファイル名を付けます。

```python theme={null}
"""chat completionsまたはgenerateContentのNano Bananaレスポンスから画像を保存する。"""
import base64
import json
import re
import sys
from pathlib import Path

DATA_URL = re.compile(r"data:image/[\w.+-]+;base64,([A-Za-z0-9+/=]+)")


def _extension(raw):
    if raw.startswith(b"\x89PNG"):
        return "png"
    if raw.startswith(b"\xff\xd8\xff"):
        return "jpg"
    if raw[:4] == b"RIFF" and raw[8:12] == b"WEBP":
        return "webp"
    return "bin"


def save_images(body, stem):
    """レスポンス本文の画像を stem.png、stem-2.png … の順に書き出す。"""
    if body.get("error"):
        raise RuntimeError(f"APIエラー: {body['error']}")
    if "choices" in body:  # chat completions：message.contentの中のデータURL
        text = body["choices"][0]["message"].get("content") or ""
        found = DATA_URL.findall(text)
        detail = text[:300]
    else:  # generateContent：inlineDataのパート。思考用のパートは最終出力ではない
        parts = [
            part
            for candidate in body.get("candidates") or []
            for part in (candidate.get("content") or {}).get("parts") or []
            if not part.get("thought")
        ]
        blobs = [part.get("inlineData") or part.get("inline_data") for part in parts]
        found = [blob["data"] for blob in blobs if blob]
        detail = body.get("promptFeedback") or [c.get("finishReason") for c in body.get("candidates") or []]
    if not found:
        raise RuntimeError(f"画像が返されませんでした: {detail!r}")
    saved = []
    for number, encoded in enumerate(found, start=1):
        encoded = "".join(encoded.split())
        raw = base64.b64decode(encoded + "=" * (-len(encoded) % 4))
        suffix = "" if number == 1 else f"-{number}"
        path = Path(f"{stem}{suffix}.{_extension(raw)}")
        path.write_bytes(raw)
        saved.append(path)
    return saved


if __name__ == "__main__":
    # cURLのあとに実行する: python nano_banana_save.py response.json 出力名
    response_body = json.loads(Path(sys.argv[1]).read_text(encoding="utf-8"))
    for saved_path in save_images(response_body, sys.argv[2]):
        print("保存しました", saved_path)
```

## 画像を編集する

同じユーザーメッセージの中に、最初に指示、そのあとに画像を入れます。ローカルのファイルは、`data:image/jpeg;base64,...` のように、MIMEタイプがファイルと一致するデータURLとして送ります。

> [tab] Python
>
> 次のスクリプトを `nano_banana_edit.py` として保存します。指示と1〜3枚の画像（ローカルのファイルか、公開されたHTTPSのURL）を送り、結果を保存します。
>
> ```python theme={null}
> """Nano Banana Standard（gemini-2.5-flash-image）で画像を編集または合成する。"""
> import argparse
> import base64
> import os
> import sys
> from pathlib import Path
>
> from openai import OpenAI
>
> from nano_banana_save import save_images
>
> MIME_TYPES = {".png": "image/png", ".jpg": "image/jpeg", ".jpeg": "image/jpeg", ".webp": "image/webp"}
>
> parser = argparse.ArgumentParser(description="画像を1枚編集する。または最大3枚を合成する。")
> parser.add_argument("prompt", help="編集の指示")
> parser.add_argument("images", nargs="+", help="ローカルのPNG、JPEG、WebPファイル、または公開されたHTTPSのURL")
> parser.add_argument("--out", default="nano-banana-edit", help="拡張子を除いた出力ファイル名")
> args = parser.parse_args()
> if len(args.images) > 3:
>     sys.exit("gemini-2.5-flash-imageの入力画像は3枚までが最適です。")
>
> content = [{"type": "text", "text": args.prompt}]
> for source in args.images:
>     if source.startswith("https://"):
>         url = source  # 公開された画像のURLはそのまま送る
>     else:
>         mime = MIME_TYPES.get(Path(source).suffix.lower())
>         if mime is None:
>             sys.exit(f"PNG、JPEG、WebPのいずれかのファイルを指定してください: {source}")
>         url = f"data:{mime};base64," + base64.b64encode(Path(source).read_bytes()).decode("ascii")
>     content.append({"type": "image_url", "image_url": {"url": url}})
>
> # max_retries=0：タイムアウト後の自動リトライで画像が二重に生成・課金されるのを防ぐ
> client = OpenAI(api_key=os.environ["LAOZHANG_API_KEY"], base_url="https://api.laozhang.ai/v1", timeout=300, max_retries=0)
> reply = client.chat.completions.create(
>     model="gemini-2.5-flash-image",
>     messages=[{"role": "user", "content": content}],
> )
> for path in save_images(reply.model_dump(), args.out):
>     print("保存しました", path)
> ```
>
> 商品写真の背景を差し替えます。
>
> ```bash theme={null}
> python nano_banana_edit.py "背景を無地の明るいグレーのスタジオの壁に置き換えてください。商品、ラベル、影はそのままにしてください。" product.jpg --out product-studio
> ```

> [tab] cURL
>
> ファイルをエンコードして `jq` で本文を組み立て、大きな画像でもシェルの引数の上限を超えないよう、本文はファイルから送ります。データURLのMIMEタイプ（ここでは `image/jpeg`）は、ファイルの形式と一致させてください。
>
> ```bash theme={null}
> base64 < product.jpg | tr -d '\n' > product.b64
> jq -n --rawfile image product.b64 '{
>   model: "gemini-2.5-flash-image",
>   stream: false,
>   messages: [{
>     role: "user",
>     content: [
>       {type: "text", text: "背景を無地の明るいグレーのスタジオの壁に置き換えてください。商品、ラベル、影はそのままにしてください。"},
>       {type: "image_url", image_url: {url: ("data:image/jpeg;base64," + $image)}}
>     ]
>   }]
> }' > edit-request.json
>
> curl --fail-with-body --max-time 300 \
>   "https://api.laozhang.ai/v1/chat/completions" \
>   -H "Authorization: Bearer $LAOZHANG_API_KEY" \
>   -H "Content-Type: application/json" \
>   --data-binary @edit-request.json \
>   -o edit-response.json
>
> python nano_banana_save.py edit-response.json product-studio
> ```

編集した画像は、モデルが返した形式に応じて `product-studio.png`、`.jpg`、`.webp` のいずれかで保存されます。変更は指示の形で書いてください。質問のように読めるプロンプトでは、テキストだけの回答が返ることがあります。

### 2〜3枚の画像を合成する

指示の後ろに、プロンプトで参照する順にファイルを並べ、それぞれの画像の役割をプロンプトで示します。

```bash theme={null}
python nano_banana_edit.py "1枚目の画像の猫を、2枚目の画像のソファの上に座らせてください。部屋の照明に合わせ、ソファはそのままにしてください。" cat.png sofa.jpg --out cat-on-sofa
```

Googleによると、`gemini-2.5-flash-image` の入力画像は3枚までが最適です。もっと多くの参照画像を使いたい場合や、複数の人物を画像間で一貫させたい場合は、最大14枚に対応する[Nano Banana 2.1](https://docs.laozhang.ai/ja/api-capabilities/nano-banana-2-1-image.md)、[Nano Banana 2](https://docs.laozhang.ai/ja/api-capabilities/nano-banana2-image.md)、[Nano Banana Pro](https://docs.laozhang.ai/ja/api-capabilities/nano-banana-pro-image-edit.md)を使ってください。

### 画像をURLで送る

ローカルのファイルの代わりに、公開された `https://` のアドレスを渡せます。スクリプトはそれを `image_url` としてそのまま送ります。

```bash theme={null}
python nano_banana_edit.py "丘の上に虹を加えてください。それ以外はすべてそのままにしてください。" https://example.com/images/hills.jpg --out hills-rainbow
```

画像はリクエストの処理中にそのアドレスから取得されるため、ログイン、Cookie、ボット対策なしで読み込める必要があります。取得できない場合は、ファイルをダウンロードしてローカルのコピーを渡してください。

## アスペクト比を指定する

OpenAI互換のルートにはアスペクト比の設定がありません。結果の形を選ぶには、Geminiネイティブのエンドポイントを呼び出し、`generationConfig.imageConfig.aspectRatio` に次のいずれかの値を指定します。

| 形 | 指定できる値 |
| - | - |
| 正方形 | `1:1` |
| 縦長 | `2:3`、`3:4`、`4:5`、`9:16` |
| 横長 | `3:2`、`4:3`、`5:4`、`16:9`、`21:9` |

* Standardはどの比率でも約1Kで出力するため、`imageSize` は省略します。
* `aspectRatio` を省略した場合、Googleのドキュメント上の既定では、出力は入力画像のサイズに合わせられます。

> [tab] cURL
>
> ```bash theme={null}
> base64 < street.jpg | tr -d '\n' > street.b64
> jq -n --rawfile image street.b64 '{
>   contents: [{
>     role: "user",
>     parts: [
>       {text: "この昼間の街の写真を、ネオンが映り込む雨の夜の風景に変えてください。建物はそのままにしてください。"},
>       {inlineData: {mimeType: "image/jpeg", data: $image}}
>     ]
>   }],
>   generationConfig: {
>     responseModalities: ["IMAGE"],
>     imageConfig: {aspectRatio: "16:9"}
>   }
> }' > native-edit-request.json
>
> curl --fail-with-body --max-time 300 \
>   "https://api.laozhang.ai/v1beta/models/gemini-2.5-flash-image:generateContent" \
>   -H "Authorization: Bearer $LAOZHANG_API_KEY" \
>   -H "Content-Type: application/json" \
>   --data-binary @native-edit-request.json \
>   -o native-edit-response.json
>
> python nano_banana_save.py native-edit-response.json street-night
> ```

> [tab] Python
>
> ```python theme={null}
> """GeminiネイティブのルートでNano Banana Standardを使い、アスペクト比を指定して画像を編集する。"""
> import base64
> import os
> import sys
> from pathlib import Path
>
> import requests
>
> from nano_banana_save import save_images
>
> image = base64.b64encode(Path("street.jpg").read_bytes()).decode("ascii")
> response = requests.post(
>     "https://api.laozhang.ai/v1beta/models/gemini-2.5-flash-image:generateContent",
>     headers={"Authorization": f"Bearer {os.environ['LAOZHANG_API_KEY']}"},
>     json={
>         "contents": [{
>             "role": "user",
>             "parts": [
>                 {"text": "この昼間の街の写真を、ネオンが映り込む雨の夜の風景に変えてください。"
>                          "建物はそのままにしてください。"},
>                 {"inlineData": {"mimeType": "image/jpeg", "data": image}},
>             ],
>         }],
>         "generationConfig": {"responseModalities": ["IMAGE"], "imageConfig": {"aspectRatio": "16:9"}},
>     },
>     timeout=300,
> )
> if response.status_code != 200:
>     sys.exit(f"HTTP {response.status_code}: {response.text[:500]}")
> for path in save_images(response.json(), "street-night"):
>     print("保存しました", path)
> ```

このルートでは、画像はファイルごとに `mimeType` を合わせた `inlineData` パートとして送ります。キーは `Authorization: Bearer` と `x-goog-api-key` のどちらでも受け付けます。Google Gen AI SDKでのクライアントの設定は、[Geminiプロトコル](https://docs.laozhang.ai/ja/api-reference/gemini.md)を参照してください。

## レスポンスを処理する

`nano_banana_save.py` は両方のレスポンス形式に対応しています。自分でレスポンスを解析する場合は、次の点に注意してください。

* **chat completions**：画像は `choices[0].message.content` のテキストの中にあり、通常は `![image](data:image/png;base64,iVBORw0...)` のようなMarkdownの画像です。PNGと決めつけずにデータURLから形式を読み取り、デコードの前に `data:image/...;base64,` の接頭辞を取り除き、長さが4の倍数でなければ `=` のパディングを補います。
* **generateContent**：各画像は `candidates[].content.parts[]` の中の `inlineData` パートで、`mimeType` とBase64の `data` を持ちます。
  * `thought: true` が付いたパートは最終出力ではないため、読み飛ばします。
* **画像がない**：返答がテキストだけか、どのパートにも `inlineData` がありません。
  * ネイティブのレスポンスでは、各候補の `finishReason` と、あれば `promptFeedback` を確認します。
  * 値の例は、`IMAGE_SAFETY`、`IMAGE_PROHIBITED_CONTENT`、`NO_IMAGE` です。

## わかりやすい編集指示を書く

* 変える部分と変えてはいけない部分を書きます。たとえば「青いソファだけを茶色の革のソファに変えてください。クッション、部屋のほかの部分、照明はそのままにしてください。」です。マスクのパラメーターはなく、Googleはこの方法をセマンティックマスキングと呼んでいます。
* 合成では、「1枚目の画像のドレス」「2枚目の画像の女性」のように、各画像を順番と役割で指します。
* 顔やロゴを守りたいときは、それを詳しく描写し、変えてはいけないと明記します。
* 「もっと良く」「きれいに」のような言葉ではなく、求めるスタイル、照明、配置を具体的に書きます。
* 精度が重要なときは、1回のリクエストで1つの変更だけにします。複数段階の編集では、保存した結果を次のリクエストの入力にします。

## エラーと課金

画像のないHTTP 200のリクエストも含め、呼び出しごとに1回の料金が課金されます。たとえば、安全チェックで出力がブロックされた場合です。同じ内容のまま再送しないでください。詳しくは[Nano Bananaの概要](https://docs.laozhang.ai/ja/api-capabilities/nano-banana-image.md)の「空のレスポンスで課金されないようにする」を参照してください。

[Nano Bananaの概要](https://docs.laozhang.ai/ja/api-capabilities/nano-banana-image.md)の「課金」のルールはすべてのNano Bananaモデルに適用され、各リクエストのステータスと課金額は[呼び出しログ](https://api.laozhang.ai/log)で確認できます。

* **HTTP 401**：APIキーと `Authorization: Bearer` ヘッダーを確認します。アカウントのAccessTokenではなく、トークン管理で作成したAPIキーを使ってください。
* **HTTP 400**：モデルID、JSONの本文、`aspectRatio` の値を確認します。Standardには `imageSize` を送らないでください。
* **HTTP 429、5xx、タイムアウト**：指数バックオフで再試行します。タイムアウトのあとは、同じ編集に二重に支払わないよう、再送する前に呼び出しログでそのリクエストを確認してください。
* **大きな写真**：Base64にするとファイルは約3分の1大きくなるため、非常に大きな画像はエンコードの前に縮小してください。

## Nano Banana 2に移行する

Nano Banana 2（`gemini-3.1-flash-image`）は、Standardと同じchat completionsと `generateContent` のリクエストを受け付けます。そのため、編集の移行で変えるのは1つの値だけです。

```diff theme={null}
- "model": "gemini-2.5-flash-image"
+ "model": "gemini-3.1-flash-image"
```

Geminiネイティブのルートでは、モデルIDはURLの一部です：`https://api.laozhang.ai/v1beta/models/gemini-3.1-flash-image:generateContent`。このページのスクリプトでは、`model` の引数かリクエストURLの `gemini-2.5-flash-image` を置き換えます。切り替えると、次のようになります。

* 1回の料金は\$0.055です（2026年9月24日時点の公開価格）。
* 編集に使える参照画像は最大14枚で、内訳はオブジェクト画像が最大10枚、人物画像が最大4枚です。
* Geminiネイティブのルートでは、14種のアスペクト比から選べ、`imageSize` に次のいずれかの値を追加できます。
  * `512`、`1K`、`2K`、`4K`
* 同じプロンプトでも結果が変わることがあるため、本番のトラフィックを移す前に、普段の編集をいくつか試してください。

Googleの画像生成ガイドは、Standardから移行するユーザーにNano Banana 2 Lite（`gemini-3.1-flash-lite-image`、1回\$0.025）を勧めています。Liteは同じリクエスト形式で、1枚の画像を1Kで編集します。

ただしGoogleによると、Liteは複数の参照入力や、複数回にわたる連続編集には最適化されていません。合成はNano Banana 2.1かNano Banana 2で行ってください。Liteの編集例は、[Nano Banana 2 Lite](https://docs.laozhang.ai/ja/api-capabilities/nano-banana-2-lite-api.md)の「画像を編集する」にあります。

## よくある質問

### gemini-2.5-flash-imageは2026年10月2日以降も使える？

現時点では使えます。Googleの料金のページは2026年10月2日での提供終了を警告していましたが、非推奨モデルのページでは現在2027年3月15日になっています（2026年10月8日時点）。2026年10月5日時点で、LaoZhang APIは `gemini-2.5-flash-image` を同じ料金で提供しています。

* LaoZhang APIは、このモデルをいつまで提供するかを保証しておらず、いつ停止してもおかしくありません。
* 停止すると、リクエストは失敗します。`-preview` のIDとは違い、ほかのモデルへの振り替えはないため、リクエストが自動で新しいモデルに移ることはありません。

編集が途切れないよう、今のうちにリクエストをNano Banana 2.1かNano Banana 2に切り替えてください。1枚の画像を1Kで編集するだけなら、Nano Banana 2 Liteでもかまいません。

### Standardの編集で2Kや4Kは出せる？

出せません。Standardはどのアスペクト比でも約1Kで出力し、`imageSize` を受け付けません。選べるのは、前述の「アスペクト比を指定する」で示した比率だけです。2Kや4Kの編集が必要な場合は、前述の「Nano Banana 2に移行する」に従って移行するか、Nano Banana Proを使い、リクエストに `imageSize` を加えてください。

### gemini-2.5-flash-image-previewはまだ使える？

使えません。Googleの[非推奨モデルのページ](https://ai.google.dev/gemini-api/docs/deprecations)によると、2026年1月15日に提供を終了しており、LaoZhang APIのモデル一覧にもありません。`gemini-2.5-flash-image` も提供終了日を過ぎていつ停止してもおかしくないため、直接Nano Banana 2（`gemini-3.1-flash-image`）に移行してください。

## 関連ページと参考資料

* [Nano Bananaの概要](https://docs.laozhang.ai/ja/api-capabilities/nano-banana-image.md) — 5モデル、2つのリクエスト形式、課金ルールの比較
* [Nano Banana 2](https://docs.laozhang.ai/ja/api-capabilities/nano-banana2-image.md) — 移行先。参照画像は最大14枚、512pxから4Kの出力
* [Nano Banana 2 Lite](https://docs.laozhang.ai/ja/api-capabilities/nano-banana-2-lite-api.md) — 低コストの1K生成と1枚の画像の編集
* [Proの編集](https://docs.laozhang.ai/ja/api-capabilities/nano-banana-pro-image-edit.md) — 最大14枚の参照画像と4K出力による複数画像の編集
* [呼び出しログ](https://docs.laozhang.ai/en/faq/call-logs.md) — リクエストのステータスと課金額の確認
* [Google: Nano Banana image generation](https://ai.google.dev/gemini-api/docs/image-generation) — 編集のプロンプト、入力の上限、モデルの選び方
* [Google: Gemini API deprecations](https://ai.google.dev/gemini-api/docs/deprecations) — `gemini-2.5-flash-image` の提供終了日
* [Google: generateContent reference](https://ai.google.dev/api/generate-content) — `imageConfig` のフィールド


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.