T-CREATOR

初めての Nano Banana:Hello World から実用サンプルまで 30 分チュートリアル

初めての Nano Banana:Hello World から実用サンプルまで 30 分チュートリアル

AI 画像生成の世界に興味があるけれど、どこから始めたらいいか分からない方も多いのではないでしょうか。今回ご紹介する Nano Banana は、Google が提供する画像生成 AI で、たった 30 分で基本から実用サンプルまで学べます。テキストから画像を生成したり、既存の画像を編集したり、驚くほど簡単に高品質な画像を作成できるんです。

このチュートリアルでは、環境構築から実際に動くコードまで、実践的な内容をステップバイステップで解説していきますね。

背景

AI 画像生成技術の進化

近年、AI 技術の発展により、テキストから画像を生成する技術が急速に進化しています。従来は専門的な画像編集ソフトやデザインスキルが必要だった作業が、AI を使えば誰でも簡単に実現できるようになりました。

Nano Banana とは

Nano Banana は、Google が開発した Gemini 2.5 Flash Image モデルの愛称です。このモデルは単なる画像生成だけでなく、画像編集や会話形式での反復的な修正にも対応している点が特徴的ですね。

以下の図は、Nano Banana の基本的な処理フローを示しています。

mermaidflowchart LR
  user["開発者"] -->|テキスト<br/>プロンプト| api["Gemini 2.5<br/>Flash Image API"]
  user -->|既存画像| api
  api -->|画像生成<br/>処理| model["Nano Banana<br/>モデル"]
  model -->|生成画像| api
  api -->|Base64 or<br/>バイナリ| user
  user -->|保存| output["PNG/JPEG<br/>ファイル"]

図で理解できる要点:

  • 開発者はテキストプロンプトまたは既存画像を API に送信
  • Nano Banana モデルが AI 処理を実行
  • 生成された画像が Base64 形式などで返却される

主な特徴

Nano Banana には以下のような魅力的な機能が搭載されています。

#機能説明
1テキストから画像生成詳細なプロンプトから高品質な画像を作成
2画像編集既存画像にテキスト指示で変更を加える
3複数入力対応複数の画像を組み合わせた出力生成
4会話型編集チャット形式で段階的に画像を精密化
5アスペクト比制御16:9、1:1 など多様な出力形式

これらの機能により、クリエイティブな作業からビジネス用途まで、幅広いシーンで活用できるでしょう。

課題

従来の画像制作における問題点

デザイナーでない開発者やビジネスパーソンが画像を作成する際、いくつかの壁に直面します。

まず、専門的な画像編集ソフトの習得には時間がかかります。Photoshop や Illustrator といったツールは高機能ですが、初心者には敷居が高いですね。

次に、外注コストの問題があります。デザイナーに依頼すると費用と時間がかかり、簡単な修正でも再依頼が必要になることも。

さらに、イメージの言語化が難しいという課題もあるでしょう。頭の中にあるアイデアを正確に伝えることは簡単ではありません。

以下の図は、従来の画像制作プロセスにおける課題を整理したものです。

mermaidflowchart TD
  start["画像が<br/>必要"] --> check{"専門<br/>スキルは?"}
  check -->|あり| tools["画像編集ソフト<br/>習得に時間"]
  check -->|なし| outsource["外注依頼"]

  tools --> timeCost["学習コスト<br/>高い"]
  outsource --> moneyCost["費用と<br/>時間がかかる"]
  outsource --> revisions["修正の<br/>やり取り"]

  timeCost --> problem["課題"]
  moneyCost --> problem
  revisions --> problem

AI 画像生成ツールの選択肢の多さ

市場には多数の AI 画像生成ツールが存在し、どれを選べばいいか迷ってしまいます。料金体系や API の使いやすさ、生成品質など、比較すべきポイントが多岐にわたりますね。

特に開発者にとっては、プログラムから簡単に呼び出せるかどうかが重要です。REST API の提供や、各種プログラミング言語向け SDK の充実度も選定基準になるでしょう。

解決策

Nano Banana を選ぶ理由

Nano Banana は前述の課題を解決する理想的なソリューションです。

開発者フレンドリーな設計により、JavaScript や TypeScript から簡単に利用できます。Google AI SDK を使えば、数行のコードで画像生成が実現可能です。

コストパフォーマンスにも優れています。1 枚あたり約$0.039(約 4 円)で、1 ドルで約 25 枚の画像を生成できるんですね。プロトタイピング段階では Google AI Studio で無料で試せるのも嬉しいポイントです。

会話型編集機能により、一度に完璧な画像を作る必要がありません。段階的に修正を重ねることで、理想の画像に近づけられます。

以下の図は、Nano Banana を使った画像生成の全体フローを示しています。

mermaidflowchart TD
  setup["環境セットアップ"] --> apikey["API Key<br/>取得"]
  apikey --> install["SDK<br/>インストール"]
  install --> code["コード実装"]

  code --> gen1["初回生成"]
  gen1 --> check{"満足?"}
  check -->|はい| save["画像保存"]
  check -->|いいえ| edit["会話型編集<br/>で微調整"]
  edit --> gen2["再生成"]
  gen2 --> check

  save --> done["完成"]

図で理解できる要点:

  • セットアップは一度だけで済む
  • 会話型編集により反復的な改善が可能
  • 満足いくまで何度でも調整できる

技術的な優位性

Nano Banana は最新の Gemini 2.5 モデルをベースとしており、高い理解力と生成品質を誇ります。複数の画像を入力として受け付けることで、画像の合成や要素の組み合わせも容易です。

アスペクト比の制御機能により、SNS 投稿用の正方形画像や YouTube サムネイル用の 16:9 画像など、用途に応じた出力が可能になっています。

具体例

環境構築

それでは実際に Nano Banana を使ってみましょう。まずは環境を準備していきます。

API Key の取得

Google AI Studio にアクセスして、API キーを取得します。

  1. Google AI Studioにアクセス
  2. 左側のナビゲーションから「Get API key」をクリック
  3. 既存または新規の Google Cloud プロジェクトを選択
  4. 必要に応じて課金設定を有効化

取得した API キーは安全に保管してください。環境変数として管理することをおすすめします。

プロジェクトのセットアップ

新しいプロジェクトディレクトリを作成し、必要なパッケージをインストールしましょう。

bashmkdir nano-banana-tutorial
cd nano-banana-tutorial
yarn init -y

必要なパッケージのインストール

Google AI SDK と型定義をインストールします。

bashyarn add @google/generative-ai
yarn add -D @types/node typescript

TypeScript 設定ファイルの作成

プロジェクトルートにtsconfig.jsonを作成します。

json{
  "compilerOptions": {
    "target": "ES2020",
    "module": "commonjs",
    "lib": ["ES2020"],
    "outDir": "./dist",
    "rootDir": "./src",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "resolveJsonModule": true
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules"]
}

この設定により、TypeScript のコンパイルオプションが適切に設定されます。

環境変数の設定

プロジェクトルートに.envファイルを作成し、API キーを設定しましょう。

textGEMINI_API_KEY=your_api_key_here

dotenv パッケージもインストールしておきます。

bashyarn add dotenv

これで環境変数から API キーを読み込めるようになりました。

Hello World: 最初の画像生成

それでは、最もシンプルな画像生成プログラムを作成していきます。

基本的な実装ファイルの作成

src​/​hello-world.tsファイルを作成します。

typescriptimport { GoogleGenerativeAI } from '@google/generative-ai';
import * as fs from 'fs';
import * as dotenv from 'dotenv';

// 環境変数の読み込み
dotenv.config();

まず必要なモジュールをインポートします。GoogleGenerativeAIがメインの SDK、fsはファイル保存用、dotenvは環境変数の読み込みに使用します。

クライアントの初期化

API キーを使ってクライアントを初期化しましょう。

typescript// APIキーの取得
const apiKey = process.env.GEMINI_API_KEY;
if (!apiKey) {
  throw new Error('GEMINI_API_KEY is not set');
}

// クライアントの初期化
const genAI = new GoogleGenerativeAI(apiKey);

環境変数から API キーを取得し、存在確認を行います。セキュリティ上、API キーは必ず環境変数で管理してください。

画像生成の実行

モデルを指定して画像を生成する関数を実装します。

typescriptasync function generateImage() {
  // モデルの取得(Nano Banana)
  const model = genAI.getGenerativeModel({
    model: "gemini-2.5-flash-image",
  });

  // プロンプトの定義
  const prompt = "緑の目をした、オレンジ色の猫がソファに座っている写真のようなリアルな画像を作成してください";

  console.log("画像を生成中...");

  // 画像生成リクエスト
  const result = await model.generateContent(prompt);
  const response = result.response;

gemini-2.5-flash-imageが Nano Banana のモデル名です。プロンプトは日本語でも問題なく動作します。

生成画像の保存処理

レスポンスから画像データを抽出して保存しましょう。

typescript  // 画像データの抽出
  const candidates = response.candidates;
  if (!candidates || candidates.length === 0) {
    throw new Error("画像生成に失敗しました");
  }

  const parts = candidates[0].content.parts;
  for (const part of parts) {
    if (part.inlineData) {
      // Base64データをバイナリに変換
      const imageData = Buffer.from(part.inlineData.data, "base64");

      // ファイルに保存
      const filename = "generated-cat.png";
      fs.writeFileSync(filename, imageData);

      console.log(`画像を保存しました: ${filename}`);
    }
  }
}

レスポンスには複数のパーツが含まれる場合があるため、ループ処理で画像データを探します。Base64 形式のデータをバイナリに変換してファイルに保存します。

エラーハンドリングとメイン実行

最後にエラーハンドリングを追加して完成です。

typescript// メイン実行
generateImage()
  .then(() => {
    console.log('処理が完了しました');
  })
  .catch((error) => {
    console.error('エラーが発生しました:', error);
    process.exit(1);
  });

エラーが発生した場合は詳細を表示し、適切に終了させます。

実行とテスト

TypeScript をコンパイルして実行してみましょう。

bashyarn tsc
node dist/hello-world.js

成功すると、generated-cat.pngというファイルが生成されます。この瞬間が一番ワクワクしますね。

実用例 1: 画像編集機能

次に、既存の画像を編集する実用的な例を見ていきましょう。

画像編集用のファイル作成

src​/​image-editor.tsを作成します。

typescriptimport { GoogleGenerativeAI } from '@google/generative-ai';
import * as fs from 'fs';
import * as dotenv from 'dotenv';

dotenv.config();

const apiKey = process.env.GEMINI_API_KEY;
if (!apiKey) {
  throw new Error('GEMINI_API_KEY is not set');
}

const genAI = new GoogleGenerativeAI(apiKey);

基本的な初期化は先ほどと同じです。

画像ファイルの読み込み関数

既存の画像を Base64 形式で読み込む関数を実装します。

typescript// 画像をBase64エンコードする関数
function fileToGenerativePart(
  path: string,
  mimeType: string
) {
  if (!fs.existsSync(path)) {
    throw new Error(`ファイルが見つかりません: ${path}`);
  }

  return {
    inlineData: {
      data: fs.readFileSync(path).toString('base64'),
      mimeType,
    },
  };
}

ファイルの存在確認を行い、バイナリデータを Base64 に変換して API に送信できる形式にします。

画像編集の実装

元画像に対して編集指示を送る処理を実装しましょう。

typescriptasync function editImage() {
  const model = genAI.getGenerativeModel({
    model: "gemini-2.5-flash-image",
  });

  // 元画像の読み込み
  const inputImage = fileToGenerativePart(
    "./input-photo.jpg",
    "image/jpeg"
  );

  // 編集指示のプロンプト
  const prompt = "この写真を鮮やかに復元し、色褪せや傷を修復してください";

  console.log("画像を編集中...");

プロンプトで具体的な編集内容を指示します。古い写真の復元や色調補正など、様々な用途に使えますね。

編集リクエストの実行と保存

画像とプロンプトを一緒に送信し、結果を保存します。

typescript  // 編集リクエスト(プロンプトと画像を配列で渡す)
  const result = await model.generateContent([prompt, inputImage]);
  const response = result.response;

  // 編集済み画像の保存
  const candidates = response.candidates;
  if (candidates && candidates.length > 0) {
    const parts = candidates[0].content.parts;
    for (const part of parts) {
      if (part.inlineData) {
        const imageData = Buffer.from(part.inlineData.data, "base64");
        fs.writeFileSync("restored-photo.png", imageData);
        console.log("編集した画像を保存しました: restored-photo.png");
      }
    }
  }
}

配列形式で複数の入力を渡すことで、テキストと画像を組み合わせた処理が可能です。

実行処理

エラーハンドリングを含めた実行処理を追加します。

typescripteditImage()
  .then(() => {
    console.log('編集処理が完了しました');
  })
  .catch((error) => {
    console.error('エラーが発生しました:', error);
    process.exit(1);
  });

実用例 2: 会話型編集

最も強力な機能の一つである会話型編集を実装していきましょう。

会話セッションの作成

src​/​chat-editor.tsを作成します。

typescriptimport { GoogleGenerativeAI } from '@google/generative-ai';
import * as fs from 'fs';
import * as dotenv from 'dotenv';

dotenv.config();

const apiKey = process.env.GEMINI_API_KEY;
if (!apiKey) {
  throw new Error('GEMINI_API_KEY is not set');
}

const genAI = new GoogleGenerativeAI(apiKey);

チャットセッションの初期化

会話型編集用のチャットセッションを開始します。

typescriptasync function chatEdit() {
  const model = genAI.getGenerativeModel({
    model: "gemini-2.5-flash-image",
  });

  // チャットセッションの開始
  const chat = model.startChat();

  console.log("会話型編集を開始します");

チャット形式により、複数回のやり取りを通じて段階的に画像を改善できます。

初回メッセージ送信

最初のメッセージで基本的な画像を生成しましょう。

typescript// 初回メッセージ(最初の画像生成)
const firstPrompt =
  '青い空と緑の草原にいる犬の画像を作成してください';
console.log(`\n[1回目] ${firstPrompt}`);

const result1 = await chat.sendMessage(firstPrompt);
const response1 = result1.response;

// 1回目の画像を保存
saveImage(response1, 'chat-step1.png');

初回は基本的な要求から始めます。この画像をベースに改善していく流れですね。

段階的な改善リクエスト

2 回目以降のメッセージで画像を改善していきます。

typescript// 2回目のメッセージ(細部の修正)
const secondPrompt =
  '犬の品種をゴールデンレトリバーに変更してください';
console.log(`\n[2回目] ${secondPrompt}`);

const result2 = await chat.sendMessage(secondPrompt);
const response2 = result2.response;

// 2回目の画像を保存
saveImage(response2, 'chat-step2.png');

前の画像の状態を引き継ぎながら、部分的な変更を加えられるのが会話型編集の強みです。

さらなる調整

3 回目以降も続けて調整できます。

typescript  // 3回目のメッセージ(装飾の追加)
  const thirdPrompt = "犬に赤い首輪とおしゃれな帽子を追加してください";
  console.log(`\n[3回目] ${thirdPrompt}`);

  const result3 = await chat.sendMessage(thirdPrompt);
  const response3 = result3.response;

  // 3回目の画像を保存
  saveImage(response3, "chat-step3.png");

  console.log("\n全ての編集が完了しました");
}

このように段階的に改善することで、最終的に理想の画像に近づけられます。

画像保存のヘルパー関数

繰り返し使う保存処理を関数化しておきましょう。

typescript// 画像保存のヘルパー関数
function saveImage(response: any, filename: string) {
  const candidates = response.candidates;
  if (candidates && candidates.length > 0) {
    const parts = candidates[0].content.parts;
    for (const part of parts) {
      if (part.inlineData) {
        const imageData = Buffer.from(
          part.inlineData.data,
          'base64'
        );
        fs.writeFileSync(filename, imageData);
        console.log(`  → 保存しました: ${filename}`);
      }
    }
  }
}

共通処理を関数化することで、コードの重複を避け、保守性が向上します。

実行処理

メイン処理を実行します。

typescriptchatEdit()
  .then(() => {
    console.log('処理が完了しました');
  })
  .catch((error) => {
    console.error('エラーが発生しました:', error);
    process.exit(1);
  });

実行すると、chat-step1.pngchat-step2.pngchat-step3.pngという 3 枚の画像が生成され、段階的な変化を確認できます。

実用例 3: アスペクト比の制御

用途に応じた画像サイズを生成する方法を見ていきましょう。

設定可能なアスペクト比

Nano Banana では以下のアスペクト比が利用できます。

#アスペクト比用途
11:1Instagram 投稿、プロフィール画像
216:9YouTube サムネイル、プレゼン資料
39:16Instagram/TikTok ストーリー
44:3標準的な画像サイズ
53:4ポートレート写真

アスペクト比指定の実装

src​/​aspect-ratio.tsを作成します。

typescriptimport { GoogleGenerativeAI } from '@google/generative-ai';
import * as fs from 'fs';
import * as dotenv from 'dotenv';

dotenv.config();

const apiKey = process.env.GEMINI_API_KEY;
if (!apiKey) {
  throw new Error('GEMINI_API_KEY is not set');
}

const genAI = new GoogleGenerativeAI(apiKey);

複数アスペクト比での一括生成

異なるアスペクト比で同じプロンプトから画像を生成します。

typescriptasync function generateWithAspectRatio() {
  const model = genAI.getGenerativeModel({
    model: "gemini-2.5-flash-image",
  });

  const prompt = "美しい夕日と海の風景";

  // 各アスペクト比で画像を生成
  const aspectRatios = ["1:1", "16:9", "9:16"];

  for (const ratio of aspectRatios) {
    console.log(`\nアスペクト比 ${ratio} で生成中...`);

ループ処理で複数のアスペクト比に対応した画像を一度に生成できます。

設定オプション付きリクエスト

アスペクト比を指定して画像を生成しましょう。

typescript// アスペクト比を指定して生成
const result = await model.generateContent({
  contents: [{ role: 'user', parts: [{ text: prompt }] }],
  generationConfig: {
    imageAspectRatio: ratio,
  },
});

const response = result.response;

generationConfigオプションでアスペクト比を指定します。この設定により、SNS や Web サイトに最適なサイズの画像が得られますね。

結果の保存

アスペクト比ごとに異なるファイル名で保存します。

typescript    // 画像の保存
    const candidates = response.candidates;
    if (candidates && candidates.length > 0) {
      const parts = candidates[0].content.parts;
      for (const part of parts) {
        if (part.inlineData) {
          const imageData = Buffer.from(part.inlineData.data, "base64");
          const filename = `sunset-${ratio.replace(":", "-")}.png`;
          fs.writeFileSync(filename, imageData);
          console.log(`  → 保存: ${filename}`);
        }
      }
    }
  }
}

ファイル名にアスペクト比を含めることで、後から判別しやすくなります。

実行処理

エラーハンドリングと実行処理を追加して完成です。

typescriptgenerateWithAspectRatio()
  .then(() => {
    console.log(
      '\n全てのアスペクト比での生成が完了しました'
    );
  })
  .catch((error) => {
    console.error('エラーが発生しました:', error);
    process.exit(1);
  });

エラーハンドリングとベストプラクティス

実用的なアプリケーションでは、適切なエラーハンドリングが重要です。

よくあるエラーと対処法

Nano Banana を使う際に遭遇しやすいエラーを整理しましょう。

#エラーコード原因対処法
1Error 401: UnauthorizedAPI キーが無効または未設定環境変数の設定を確認
2Error 429: Too Many Requestsリクエスト制限超過リトライロジックを実装
3Error 500: Internal Server Errorサーバー側の一時的な問題時間をおいて再試行
4TypeError: Cannot read propertyレスポンスの構造が想定と異なるnull/undefined チェックを追加

リトライロジックの実装

一時的なエラーに対応するリトライ機能を実装します。

typescript// リトライ機能付き画像生成
async function generateWithRetry(
  model: any,
  prompt: string,
  maxRetries: number = 3
) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      console.log(`試行 ${i + 1}/${maxRetries}...`);
      const result = await model.generateContent(prompt);
      return result;
    } catch (error: any) {
      console.error(`エラー: ${error.message}`);

リトライ回数を制限し、ループ内で処理を実行します。

待機時間を含むリトライ処理

指数バックオフで待機時間を設定しましょう。

typescript      // 最後の試行でなければ待機
      if (i < maxRetries - 1) {
        const waitTime = Math.pow(2, i) * 1000; // 指数バックオフ
        console.log(`${waitTime}ms 待機後に再試行します...`);
        await new Promise((resolve) => setTimeout(resolve, waitTime));
      } else {
        // 最後の試行でも失敗した場合
        throw new Error(`${maxRetries}回の試行後も失敗しました`);
      }
    }
  }
}

指数バックオフにより、サーバーへの負荷を軽減しながら再試行できます。

プロンプトのベストプラクティス

高品質な画像を生成するためのプロンプト作成のコツをまとめます。

typescript// 良いプロンプトの例
const goodPrompt = `
  フォトリアリスティックな画像を作成:
  - 被写体: 笑顔の女性
  - 年齢: 30代
  - 服装: ビジネスカジュアル
  - 背景: 明るいオフィス空間
  - 照明: 自然光、柔らかい影
  - スタイル: プロフェッショナルな雰囲気
`.trim();

詳細かつ具体的に指示することで、望み通りの画像が生成されやすくなります。

パフォーマンス最適化

複数の画像を効率的に生成する方法を見ていきましょう。

バッチ処理の実装

複数のプロンプトを並列処理します。

typescriptasync function batchGenerate(prompts: string[]) {
  const model = genAI.getGenerativeModel({
    model: "gemini-2.5-flash-image",
  });

  console.log(`${prompts.length}件の画像を並列生成します`);

  // Promise.allで並列実行
  const results = await Promise.all(
    prompts.map((prompt, index) =>
      model
        .generateContent(prompt)
        .then((result) => ({ index, result, success: true }))
        .catch((error) => ({ index, error, success: false }))
    )
  );

Promise.allを使うことで、複数のリクエストを同時に処理できます。ただし、レート制限には注意が必要ですね。

結果の処理とログ出力

成功・失敗を分けて処理しましょう。

typescript  // 結果の処理
  results.forEach((item) => {
    if (item.success && "result" in item) {
      console.log(`✓ プロンプト${item.index + 1}: 成功`);
      // 画像保存処理
      saveImage(item.result.response, `batch-${item.index + 1}.png`);
    } else if ("error" in item) {
      console.error(`✗ プロンプト${item.index + 1}: 失敗 - ${item.error}`);
    }
  });

  return results;
}

成功した画像のみを保存し、失敗したものはログに記録します。

まとめ

このチュートリアルでは、Nano Banana の基礎から実用的なサンプルまで、30 分で学べる内容をご紹介しました。

まず環境構築では、Google AI Studio での API キー取得から、TypeScript プロジェクトのセットアップまでを実施しました。Hello World では、テキストプロンプトから画像を生成する基本的な流れを体験できましたね。

実用例として、既存画像の編集、会話型での段階的な改善、アスペクト比の制御という 3 つのパターンを実装しました。それぞれが異なるユースケースに対応しており、実際のプロジェクトですぐに活用できる内容です。

エラーハンドリングやリトライロジック、バッチ処理といった実践的なテクニックも押さえました。これらのベストプラクティスを活用することで、本番環境でも安心して使えるアプリケーションが構築できるでしょう。

Nano Banana の魅力は、何といっても手軽さと高品質の両立にあります。コストパフォーマンスにも優れており、個人開発者から企業まで幅広く利用できますね。

今後は、生成した画像を Web アプリケーションに組み込んだり、マーケティング素材の自動生成システムを構築したり、可能性は無限大です。ぜひこのチュートリアルをベースに、あなた独自の活用方法を見つけてください。

AI による画像生成は、これからますます身近な技術になっていきます。今日学んだ知識を活かして、クリエイティブな作業を効率化し、新しい価値を生み出していきましょう。

関連リンク