AI画像生成でアプリケーションを構築するのは魔法のようですが、複雑なAPIドキュメント、認証の煩雑さ、デバッグの悪夢に直面するまでは、そう感じられるでしょう。Nano Banana 2が何をもたらすか、すでにご覧になっているはずです。テキストプロンプトから生成される息をのむような画像、Flashのような速度で生成されるプロ品質の出力、そして複数画像のワークフローを可能にする被写体の一貫性といった機能です。しかし、それを実際に自分のコードベースに統合するとなると、多くの開発者が行き詰まってしまいます。
おそらく、Googleのドキュメントを読み解き、認証フローをつなぎ合わせ、CLIで手動でリクエストをテストしようと試みたことがあるでしょう。すでに、誤った形式のリクエストのデバッグでAPIクォータを使い果たしたり、画像が毎回ぼやけて返ってくる理由を疑問に思ったりしたかもしれません。実のところ、新しいAPI、特にNano Banana 2のような強力なAPIを統合するには、ドキュメントを読むだけでは不十分です。迅速にテストし、プロンプトを繰り返し改善し、API呼び出しを効率的に管理できるワークフローが必要です。
このガイドでは、Google CloudプロジェクトのセットアップからPythonおよびJavaScriptで本番環境対応のコードを記述するまで、Nano Banana 2をアプリケーションに統合するために必要なすべてを順を追って説明します。しかし、このガイドが他と違うのは、Apidogを使用してすべてのステップをテストおよびデバッグする方法を紹介することです。これにより、単にコードをコピーするだけでなく、維持および拡張可能なワークフローを構築することができます。
前提条件
始める前に、以下を用意してください。
- Google Cloudアカウント(またはcloud.google.comでサインアップ)
- REST APIに関する基本的な理解
- Python 3.8+ または Node.js 18+ がインストールされていること
- テスト用のApidogなどのAPIクライアント
このガイドでは、HTTPリクエストの作成とJSONデータの処理に慣れていることを前提としています。APIに初めて触れる方は、APIの基本については弊社のAPIテストガイドをご覧ください。
Google Cloudプロジェクトのセットアップ
Nano Banana 2 APIを使用するには、Generative Language APIが有効になっているGoogle Cloudプロジェクトが必要です。
ステップ1:新しいプロジェクトを作成する
- Google Cloud Consoleにアクセスする
- 「プロジェクトを選択」→「新しいプロジェクト」をクリックする
- プロジェクト名(例: "nano-banana-image-gen")を入力する
- 「作成」をクリックする
- プロジェクトが作成されるまで待つ

ステップ2:APIアクセスを設定する
- 「APIとサービス」→「認証情報」に移動する
- 「認証情報を作成」→「APIキー」をクリックする
- APIキーをコピーする(後で必要になります)

プロのヒント:
APIキーの取得
APIアクセスを取得する方法は2つあります。
オプション1:Google Cloud Console(本番環境に推奨)
上記の手順に従ってください。作成したAPIキーがアクセス認証情報となります。
オプション2:Google AI Studio(開発環境に推奨)
- Google AI Studioにアクセスする
- Googleアカウントでサインインする
- ナビゲーションで「APIキーを取得」をクリックする
- 「APIキーを作成」をクリックする(または既存のプロジェクトを選択する)
- APIキーをコピーする

AI Studioキーは開発とテストに適しています。本番環境では、より良い管理とセキュリティのためにGoogle Cloud Consoleのキーを使用してください。
初めてのAPIリクエスト
すべてが機能することを確認するために、簡単な画像生成リクエストをしてみましょう。
cURLの使用
curl -X POST \
"https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash-exp-image-generation:predict?key=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"prompt": "A cute banana character wearing sunglasses, fun cartoon style",
"number_of_images": 1
}'
レスポンスの理解
{
"predictions": [
{
"image": {
"mimeType": "image/png",
"data": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg=="
},
"generatedImageId": "img_abc123xyz",
"metadata": {
"prompt": "A cute banana character wearing sunglasses, fun cartoon style",
"seed": 12345,
"finishReason": "SUCCESS"
}
}
],
"metadata": {
"modelVersion": "gemini-3.1-flash-image-preview",
"processingTimeMs": 1250,
"contentAuthenticity": {
"synthID": "enabled",
"c2pa": "enabled"
}
}
}
dataフィールドには、base64エンコードされたPNG画像が含まれています。画像を保存または表示するには、これをデコードする必要があります。
Pythonとの統合
Nano Banana 2をPythonアプリケーションに統合する方法は次のとおりです。
クライアントライブラリのインストール
pip install google-generativeai
基本的な画像生成
import google.generativeai as genai
import base64
import os
# APIキーでAPIを設定する
genai.configure(api_key=os.environ.get("GEMINI_API_KEY"))
# モデルを作成する
model = genai.GenerativeModel("gemini-3.1-flash-image-preview")
# 画像を生成する
response = model.generate_images(
prompt="自然光が差し込むモダンなミニマリストオフィス、観葉植物、スタンディングデスク、4K品質",
number_of_images=1
)
# 画像を保存する
if response.generated_images:
image_data = response.generated_images[0].image_bytes
with open("output_image.png", "wb") as f:
f.write(image_data)
print("画像は output_image.png に保存されました")
パラメータを使用した高度な画像生成
import google.generativeai as genai
from PIL import Image
import io
genai.configure(api_key=os.environ.get("GEMINI_API_KEY"))
model = genai.GenerativeModel("gemini-3.1-flash-image-preview")
# 高度なパラメータで生成する
response = model.generate_images(
prompt="ネオンライト、空飛ぶ車、サイバーパンクの美学が特徴の未来的な夜の都市景観",
number_of_images=1,
aspect_ratio="16:9",
negative_prompt="ぼやけた、低品質な、歪んだ、醜い",
safety_filter_level="block_medium_and_above"
)
# レスポンスを処理する
for idx, generated_image in enumerate(response.generated_images):
# PIL画像に変換する
image = Image.open(io.BytesIO(generated_image.image_bytes))
# カスタム名で保存する
image.save(f"generated_image_{idx}.png")
# メタデータにアクセスする
print(f"画像 {idx}: {generated_image.finish_reason}")
print(f"シード: {generated_image.seed}")
バッチ画像生成
import google.generativeai as genai
import os
genai.configure(api_key=os.environ.get("GEMINI_API_KEY"))
model = genai.GenerativeModel("gemini-3.1-flash-image-preview")
# 複数の画像を一度に生成する
prompts = [
"山道を行く赤いスポーツカー",
"居心地の良いコーヒーショップの店内",
"ミニマリストな寝室のデザイン",
"熱帯のビーチの夕日"
]
# すべての画像を生成する
for idx, prompt in enumerate(prompts):
response = model.generate_images(
prompt=prompt,
number_of_images=1,
aspect_ratio="16:9"
)
if response.generated_images:
image_data = response.generated_images[0].image_bytes
with open(f"image_{idx + 1}.png", "wb") as f:
f.write(image_data)
print(f"生成済み: image_{idx + 1}.png")
キャラクターの一貫性の例
import google.generativeai as genai
genai.configure(api_key=os.environ.get("GEMINI_API_KEY"))
model = genai.GenerativeModel("gemini-3.1-flash-image-preview")
# 基本的なキャラクターの説明
base_character = "丸い体、青い目、頭にアンテナを持つ、白と水色の配色のかわいい漫画ロボット"
# 基本的なキャラクターを生成する(一貫性のためシードに注意)
response1 = model.generate_images(
prompt=base_character + ", 正面からのビュー, 立っているポーズ",
number_of_images=1,
seed=42 # 重要: このシードに注意
)
base_seed = response1.generated_images[0].seed
print(f"基本キャラクターのシード: {base_seed}")
# 同じシードを使用してバリエーションを生成する
poses = [
"座っているポーズ",
"手を振る",
"ボールを持っている",
"歩いている"
]
for pose in poses:
response = model.generate_images(
prompt=f"{base_character}, {pose}, シード {base_seed} と同じキャラクター",
number_of_images=1,
seed=base_seed # 同じシードで一貫性を維持する
)
if response.generated_images:
filename = f"robot_{pose.replace(' ', '_')}.png"
with open(filename, "wb") as f:
f.write(response.generated_images[0].image_bytes)
print(f"生成済み: {filename}")
JavaScript/Node.jsとの統合
クライアントライブラリのインストール
npm install @google/generative-ai
基本的な画像生成
const { GoogleGenerativeAI } = require("@google/generative-ai");
const fs = require("fs");
const path = require("path");
// APIキーで初期化する
const genAI = new GoogleGenerativeAI(process.env.GEMINI_API_KEY);
async function generateImage() {
// モデルを取得する
const model = genAI.getGenerativeModel({
model: "gemini-3.1-flash-image-preview",
});
// 画像を生成する
const result = await model.generateImages({
prompt: "ヤシの木のシルエットと海に沈む美しい夕日",
numberOfImages: 1,
});
// レスポンスを処理する
if (result.generatedImages && result.generatedImages.length > 0) {
const imageData = result.generatedImages[0].imageBytes;
// ファイルに保存する
fs.writeFileSync("sunset.png", Buffer.from(imageData, "base64"));
console.log("画像は sunset.png に保存されました");
// メタデータをログに出力する
console.log("シード:", result.generatedImages[0].seed);
console.log("終了理由:", result.generatedImages[0].finishReason);
}
}
generateImage().catch(console.error);
Base64レスポンスの処理
const { GoogleGenerativeAI } = require("@google/generative-ai");
const fs = require("fs");
const genAI = new GoogleGenerativeAI(process.env.GEMINI_API_KEY);
async function generateAndProcessImage() {
const model = genAI.getGenerativeModel({
model: "gemini-3.1-flash-image-preview",
});
const result = await model.generateImages({
prompt: "ビジネススーツを着た人物のプロフェッショナルな顔写真、スタジオ照明",
numberOfImages: 1,
aspectRatio: "1:1",
resolution: "1024x1024"
});
const generatedImage = result.generatedImages[0];
// base64をデコードする
const imageBuffer = Buffer.from(generatedImage.imageBytes, "base64");
// ファイル名にメタデータを含めて保存する
const filename = `portrait_${generatedImage.seed}.png`;
fs.writeFileSync(filename, imageBuffer);
return {
filename,
seed: generatedImage.seed,
finishReason: generatedImage.finishReason
};
}
generateAndProcessImage()
.then(info => console.log("生成済み:", info))
.catch(err => console.error("エラー:", err));
Express.js REST APIの例
const express = require("express");
const { GoogleGenerativeAI } = require("@google/generative-ai");
const multer = require("multer");
const fs = require("fs");
const app = express();
const genAI = new GoogleGenerativeAI(process.env.GEMINI_API_KEY);
app.use(express.json());
// 画像生成エンドポイント
app.post("/api/generate", async (req, res) => {
try {
const { prompt, aspect_ratio, negative_prompt, number_of_images } = req.body;
const model = genAI.getGenerativeModel({
model: "gemini-2.0-flash-exp-image-generation",
});
const result = await model.generateImages({
prompt,
numberOfImages: number_of_images || 1,
aspectRatio: aspect_ratio || "1:1",
negativePrompt: negative_prompt
});
// レスポンスのために画像をbase64に変換する
const images = result.generatedImages.map((img, idx) => ({
id: idx,
seed: img.seed,
finishReason: img.finishReason,
data: img.imageBytes // Base64エンコード済み
}));
res.json({
success: true,
images,
metadata: {
modelVersion: result.response?.metadata?.modelVersion,
processingTimeMs: result.response?.metadata?.processingTimeMs
}
});
} catch (error) {
console.error("生成エラー:", error);
res.status(500).json({
success: false,
error: error.message
});
}
});
// バッチ生成エンドポイント
app.post("/api/generate/batch", async (req, res) => {
try {
const { prompts } = req.body;
const model = genAI.getGenerativeModel({
model: "gemini-3.1-flash-image-preview",
});
const results = [];
for (const prompt of prompts) {
const result = await model.generateImages({
prompt,
numberOfImages: 1
});
results.push({
prompt,
seed: result.generatedImages[0]?.seed,
success: !!result.generatedImages[0]
});
}
res.json({ success: true, results });
} catch (error) {
res.status(500).json({ success: false, error: error.message });
}
});
app.listen(3000, () => {
console.log("サーバーはポート 3000 で稼働しています");
});
高度なパラメータ
Nano Banana 2は、画像生成を微調整するためのさまざまなパラメータをサポートしています。
パラメータリファレンス
| パラメータ | 型 | 説明 | 例 |
|---|---|---|---|
prompt | string | 目的の画像のテキスト説明 | "マットに座っている猫" |
number_of_images | integer | 生成する画像の数 (1-4) | 2 |
aspect_ratio | string | 画像のアスペクト比 | "16:9", "1:1", "4:3" |
resolution | string | 出力解像度 | "1024x1024", "2048x2048" |
negative_prompt | string | 除外する要素 | "ぼやけた、透かし" |
seed | integer | 再現性のためのランダムシード | 12345 |
safety_filter_level | string | コンテンツフィルタリング | "block_medium_and_above" |
解像度オプション
# 利用可能な解像度
resolutions = [
"512x512", # サムネイル、ソーシャルメディア
"768x768", # 小さなウェブ画像
"1024x1024", # 標準の正方形
"1024x768", # 4:3 横長
"1280x720", # HDレディ
"1920x1080", # フルHD
"2048x2048", # 高品質
"3840x2160" # 4K
]
# 特定の解像度を使用する
response = model.generate_images(
prompt="時計のプロフェッショナルな商品写真",
resolution="2048x2048"
)
アスペクト比
aspect_ratios = [
"1:1", # 正方形 (Instagramの投稿)
"4:3", # 標準写真
"16:9", # 横長 (YouTube、ウェブ)
"9:16", # 縦長 (ストーリー、TikTok)
"21:9", # ウルトラワイド
"3:4", # 標準の縦長
"2:3" # 縦長写真
]
# 特定のアスペクト比を使用する
response = model.generate_images(
prompt="モダンなオフィスインテリアデザイン",
aspect_ratio="16:9"
)
レスポンスの処理
レスポンス構造の解析
import google.generativeai as genai
genai.configure(api_key=os.environ.get("GEMINI_API_KEY"))
model = genai.GenerativeModel("gemini-3.1-flash-image-preview")
response = model.generate_images(
prompt="山の上に建つファンタジーのお城",
number_of_images=2
)
# 予測(生成された画像)にアクセスする
for idx, image in enumerate(response.generated_images):
print(f"画像 {idx + 1}:")
print(f" - シード: {image.seed}")
print(f" - 終了理由: {image.finish_reason}")
print(f" - 画像バイト長: {len(image.image_bytes)}")
# メタデータにアクセスする
print("\nメタデータ:")
print(f" - モデルバージョン: {response.response.metadata.model_version}")
print(f" - 処理時間: {response.response.metadata.processing_time_ms}ms")
print(f" - SynthID: {response.response.metadata.content_authenticity.synth_id}")
異なる形式への変換
from PIL import Image
import io
import base64
def image_to_different_formats(image_bytes):
"""生成された画像を複数の形式に変換する。"""
# PIL画像として読み込む
img = Image.open(io.BytesIO(image_bytes))
# PNGとして保存する
img.save("image.png", "PNG")
# JPEGとして保存する(品質指定)
img.save("image.jpg", "JPEG", quality=95)
# WebPに変換する(ファイルサイズが小さい)
img.save("image.webp", "WEBP", quality=85)
# 埋め込み用にbase64を取得する
buffered = io.BytesIO()
img.save(buffered, format="PNG")
base64_str = base64.b64encode(buffered.getvalue()).decode()
return base64_str
エラー処理
適切なエラー処理は、本番環境のアプリケーションにとって不可欠です。
Pythonのエラー処理
import google.generativeai as genai
from google.api_core.exceptions import (
ResourceExhausted,
InvalidArgument,
ServiceUnavailable
)
genai.configure(api_key=os.environ.get("GEMINI_API_KEY"))
model = genai.GenerativeModel("gemini-3.1-flash-image-preview")
def generate_image_with_retry(prompt, max_retries=3):
"""リトライロジック付きで画像を生成する。"""
for attempt in range(max_retries):
try:
response = model.generate_images(
prompt=prompt,
number_of_images=1
)
return response
except ResourceExhausted as e:
# レート制限またはクォータ超過
print(f"レート制限されました (試行 {attempt + 1}/{max_retries})")
if attempt < max_retries - 1:
import time
time.sleep(2 ** attempt) # 指数バックオフ
else:
raise Exception("レート制限を超過しました。後でもう一度お試しください。")
except InvalidArgument as e:
# 無効なプロンプトまたはパラメータ
raise ValueError(f"無効なリクエスト: {e}")
except ServiceUnavailable as e:
# サービスが一時的に利用不能
print(f"サービスが利用できません (試行 {attempt + 1}/{max_retries})")
if attempt < max_retries - 1:
import time
time.sleep(5) # 5秒待機
else:
raise Exception("サービスが利用できません。後でもう一度お試しください。")
return None
# 使用例
try:
result = generate_image_with_retry("美しい風景")
if result:
print("画像が正常に生成されました")
except Exception as e:
print(f"エラー: {e}")
JavaScriptのエラー処理
const { GoogleGenerativeAI } = require("@google/generative-ai");
const genAI = new GoogleGenerativeAI(process.env.GEMINI_API_KEY);
async function generateImageWithRetry(prompt, maxRetries = 3) {
const model = genAI.getGenerativeModel({
model: "gemini-3.1-flash-image-preview",
});
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
const result = await model.generateImages({
prompt,
numberOfImages: 1
});
return result;
} catch (error) {
console.error(`試行 ${attempt + 1} が失敗しました:`, error.message);
if (error.message.includes("RESOURCE_EXHAUSTED")) {
// レート制限
const delay = Math.pow(2, attempt) * 1000;
console.log(`レート制限されました。${delay}ms後にリトライします...`);
await new Promise(resolve => setTimeout(resolve, delay));
} else if (error.message.includes("INVALID_ARGUMENT")) {
// 無効なプロンプト
throw new Error(`無効なプロンプト: ${error.message}`);
} else if (attempt === maxRetries - 1) {
throw error;
}
}
}
return null;
}
// 使用例
generateImageWithRetry("日の出の穏やかな山の湖")
.then(result => {
if (result) {
console.log("画像が正常に生成されました");
}
})
.catch(err => {
console.error("画像の生成に失敗しました:", err.message);
});
一般的なエラーコード
| エラーコード | 説明 | 解決策 |
|---|---|---|
| 400 | 無効なリクエストパラメータ | プロンプト、アスペクト比、解像度を確認してください |
| 403 | APIキーが無効、または権限がない | APIキーと権限を確認してください |
| 429 | レート制限を超過 | バックオフを実装し、リクエスト頻度を減らしてください |
| 500 | 内部サーバーエラー | 指数バックオフで再試行してください |
| 503 | サービスが利用不能 | 待機して再試行してください |
Apidogでのテスト
Apidogは、Nano Banana 2 API統合をテストおよびデバッグするための優れたツールです。
Apidogワークスペースのセットアップ
- Apidogを開き、新しいプロジェクトを作成する
- 環境変数を追加する:
GEMINI_API_KEY: あなたの_api_キー_ここ
BASE_URL: https://generativelanguage.googleapis.com/v1beta

APIリクエストの作成
エンドポイント: POST /models/gemini-3.1-flash-image-preview:predict
ヘッダー:
Authorization: Bearer {{GEMINI_API_KEY}}
Content-Type: application/json

リクエストボディ:
{
"prompt": "{{prompt}}",
"number_of_images": 1,
"aspect_ratio": "1:1"
}
クエリパラメータ:
key: {{GEMINI_API_KEY}}
テストスクリプトの記述
// テスト: 正常な生成
pm.test("画像生成は成功しました", function() {
var jsonData = pm.response.json();
pm.expect(jsonData.predictions).to.have.property('image');
pm.expect(jsonData.predictions[0].metadata.finishReason).to.eql('SUCCESS');
});
// テスト: レスポンスにメタデータが含まれていること
pm.test("レスポンスに必要なメタデータがあること", function() {
var jsonData = pm.response.json();
pm.expect(jsonData.metadata).to.have.property('modelVersion');
pm.expect(jsonData.metadata).to.have.property('processingTimeMs');
});
// テスト: コンテンツの真正性が検証されていること
pm.test("コンテンツの真正性が有効になっていること", function() {
var jsonData = pm.response.json();
pm.expect(jsonData.metadata.contentAuthenticity.synthID).to.eql('enabled');
});
// テスト: 許容できるレスポンス時間
pm.test("レスポンス時間が5秒未満であること", function() {
pm.expect(pm.response.responseTime).to.be.below(5000);
});
バッチテスト用のコレクションの作成
これらのリクエストをApidogに保存して、テストコレクションを構築します。
- 基本的な生成 - 単一画像の生成
- バッチ生成 - 複数のプロンプト
- キャラクターの一貫性 - 同じシードのテスト
- エラー処理 - 無効なプロンプトのテスト
- パフォーマンステスト - 複数の同時リクエスト
本番環境でのベストプラクティス
本番環境でNano Banana 2をデプロイする場合:
1. APIキーを保護する
# APIキーをハードコードしてはいけません
# 環境変数を使用する
import os
API_KEY = os.environ.get("GEMINI_API_KEY")
# またはシークレットマネージャーを使用する
# AWS Secrets Manager, HashiCorp Vaultなど
2. キャッシュを実装する
import hashlib
import redis
redis_client = redis.Redis(host='localhost', port=6379, db=0)
def generate_image_cached(prompt, seed=None):
"""キャッシュ付きで画像を生成する。"""
# プロンプト + シードからキャッシュキーを作成する
cache_key = f"image:{hashlib.md5(f'{prompt}:{seed}'.encode()).hexdigest()}"
# キャッシュを確認する
cached = redis_client.get(cache_key)
if cached:
return cached
# 新しい画像を生成する
response = model.generate_images(prompt=prompt, seed=seed)
image_data = response.generated_images[0].image_bytes
# 24時間キャッシュする
redis_client.setex(cache_key, 86400, image_data)
return image_data
3. レート制限
from flask import Flask, request, jsonify
from flask_limiter import Limiter
app = Flask(__name__)
limiter = Limiter(app, key_func=lambda: request.headers.get("X-API-Key"))
@app.route("/generate", methods=["POST"])
@limiter.limit("10 per minute") # クォータに基づいて調整する
def generate():
# 生成ロジック
pass
4. 監視とロギング
import logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
def generate_with_logging(prompt):
logger.info(f"プロンプトのために画像を生成中: {prompt[:50]}...")
start_time = time.time()
try:
response = model.generate_images(prompt=prompt)
elapsed = time.time() - start_time
logger.info(f"正常に生成されました。時間: {elapsed:.2f}秒")
return response
except Exception as e:
elapsed = time.time() - start_time
logger.error(f"{elapsed:.2f}秒後に失敗しました: {e}")
raise
5. 非同期処理のためのウェブフック
大規模なバッチジョブには、ウェブフックを使用します。
# ウェブフック付きリクエスト
response = model.generate_images(
prompt="商品画像を10枚生成する",
number_of_images=10,
webhook_url="https://your-server.com/webhook/nano-banana"
)
# ウェブフックハンドラー
@app.route("/webhook/nano-banana", methods=["POST"])
def handle_webhook():
data = request.json
if data["status"] == "completed":
images = data["images"]
# 完了した画像を処理する
elif data["status"] == "failed":
# 失敗を処理する
pass
return jsonify({"received": True})
結論
Nano Banana 2 APIは、AI画像生成をアプリケーションに統合するための強力な方法を提供します。複数のプログラミング言語のサポート、柔軟なパラメータ、堅牢なエラー処理により、シンプルな画像ジェネレーターから複雑な本番ワークフローまで、あらゆるものを構築できます。
主なポイント:
- 始めるには Google CloudプロジェクトとAPIキーが必要です。
- PythonとJavaScript SDKは統合を容易にします。
- シードやネガティブプロンプトなどの高度なパラメータにより、きめ細かな制御が可能です。
- ApidogはAPI統合のテストとデバッグに役立ちます。
- 本番環境でのデプロイには、セキュリティ、キャッシング、レート制限、監視が必要です。
このガイドの基本的な例から始め、APIに慣れるにつれて段階的に高度な機能を追加していきましょう。
次のステップ:
