0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

nanobanana API で画像を生成

Last updated at Posted at 2025-10-11

APIキーを作成

googlestudioから作成

右上からAPIキーを作成する。
また、プロジェクトをインポートするか聞かれるので
自分の場合はインポートした。

1.png

赤丸のキーをクリックするとAPIキーが表示される。
tierの切り替えがあるが、無料から有料にしますか?の違い。
とりあえず無料版でも利用できるのでtier1のまま利用

APIキーを .env に設定

GEMINI_API_KEY="yourkey"

コード

// 1. APIキーを設定
        $apiKey = env("GEMINI_API_KEY");

// 画像生成モデルのエンドポイント
        $url = 'https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash-image:generateContent?key=' . $apiKey;

        $body = [
            'contents' => [[
                'role' => 'user',
                'parts' => [
                    ['text' => '名古屋駅の夜景をリアルに、16:9構図で']
                ]
            ]],
            'generationConfig' => [
                'responseModalities' => ['Image'],
                'imageConfig' => ['aspectRatio' => '16:9'],
            ],
        ];

// HTTPリクエスト送信
        $response = Http::withHeaders(['Content-Type' => 'application/json'])
            ->post($url, $body)
            ->json();

// 画像データ抽出
        $parts = $response['candidates'][0]['content']['parts'] ?? [];
        $imageB64 = null;
        $mime = null;

        foreach ($parts as $p) {
            if (isset($p['inlineData']['data'])) {
                $imageB64 = $p['inlineData']['data'];
                $mime = $p['inlineData']['mimeType'] ?? 'image/png';
                break;
            }
            if (isset($p['inline_data']['data'])) {
                $imageB64 = $p['inline_data']['data'];
                $mime = $p['inline_data']['mime_type'] ?? 'image/png';
                break;
            }
        }

        if (!$imageB64) {
            dd('画像データなし', $response);
        }

// Base64をデコードして保存
        $imageBinary = base64_decode(strtr($imageB64, '-_', '+/'), true);
        if ($imageBinary === false) {
            dd('Base64デコード失敗');
        }

// Laravelのデフォルトstorageパス
        $path = storage_path('app/output.png');

// 保存
        file_put_contents($path, $imageBinary);

        echo "画像を保存しました: {$path}";

これで /storage/app/output.png に画像が保存される。

作成された画像

output.png

写真をアップして、その写真をもとに変更

img/girl.jpg を 歯を見せて笑わせて
storage/girl_smile.jpg に保存

        // APIキーを .env に設定(GOOGLE_API_KEY=xxxx)
        $apiKey = env('GEMINI_API_KEY');

        $url = "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash-image:generateContent?key={$apiKey}";

// 入力画像パス(Laravel標準 storage)
        $inputPath = storage_path('img/girl.jpg');
        if (!file_exists($inputPath)) {
            throw new Exception("画像が見つかりません: {$inputPath}");
        }

// 画像をBase64エンコード
        $imageBase64 = base64_encode(file_get_contents($inputPath));

// Geminiへのリクエスト内容
        $body = [
            'contents' => [[
                'role' => 'user',
                'parts' => [
                    [
                        'inline_data' => [
                            'mime_type' => 'image/jpeg',
                            'data' => $imageBase64
                        ]
                    ],
                    [
                        'text' => '歯を見せて笑わせて'
                    ]
                ]
            ]],
            'generationConfig' => [
                'responseModalities' => ['Image'],
                'imageConfig' => ['aspectRatio' => '1:1'],
            ],
        ];

// リクエスト送信
        $response = Http::withHeaders(['Content-Type' => 'application/json'])
            ->post($url, $body)
            ->json();

// Base64画像を取得
        $parts = $response['candidates'][0]['content']['parts'] ?? [];
        $imageB64 = null;
        foreach ($parts as $p) {
            if (isset($p['inlineData']['data'])) {
                $imageB64 = $p['inlineData']['data'];
                break;
            }
            if (isset($p['inline_data']['data'])) {
                $imageB64 = $p['inline_data']['data'];
                break;
            }
        }

        if (!$imageB64) {
            throw new Exception('画像データが取得できませんでした: ' . json_encode($response, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));
        }

// Base64デコードして保存
        $binary = base64_decode(strtr($imageB64, '-_', '+/'), true);
        $outputPath = storage_path('girl_smile.jpg');
        file_put_contents($outputPath, $binary);

        echo "笑顔画像を保存しました: {$outputPath}";

変換前

akiIMG_6549_TP_V4.jpg

変換後

girl_smile.jpg

使い方のコツ

NanoBanana(Gemini 2.5 Flash Image)をAPIで使う最短メモ

アイデア

・女の子の画像を1枚指定してアップすれば、同一人物のいろんな場面が作れそう
・アカウント名やHNなども一緒にアップし、透かしを入れれば、より本物に近い女の子を生成できそう

先に結論

  • 透かしはオフにできない(不可視の SynthID が常に埋め込まれる)
  • 料金は 出力100万トークン=$301024×1024は1枚=1290トークン=約$0.039(約6円/1ドル=150円)
  • テキスト→画像、画像+テキストでの編集、マルチ画像合成、反復調整に対応
  • REST/SDKで**gemini-2.5-flash-image** を指定して使う。プレビュー系は2025-10-31に廃止、移行必須

できること

  • Text-to-Image:テキストから画像生成
  • 画像編集(Image + Text):要素の追加/削除/スタイル変更/カラー調整
  • マルチ画像→画像:複数画像で構図合成・スタイル転写(入力は最大3枚が最適)
  • 反復調整:会話で少しずつ修正
  • 高忠実度テキスト描画:ロゴやポスターで文字を崩さず生成

透かし(Watermark)

  • すべての生成/編集画像に不可視の SynthID が入る
  • 可視の有無はワークフロー依存だがAPIで無効化は不可
  • SynthID は DeepMind/Google の公式仕様で埋め込まれる

料金(日本円併記・1USD=150円)

  • 出力:$30/100万tokens
  • 例)1024×1024 は1290tokens ≒ $0.039 ≒ 約6円/枚
  • 例)1,000枚(1024×1024) ≒ $39(約5,850円)

モデル指定

  • gemini-2.5-flash-image(本番運用向け)
  • プレビュー版(…preview…)は2025-10-31 廃止

アスペクト比とサイズ

  • 入力画像があれば出力は入力サイズに追従
  • なければ**正方形(1:1)**がデフォルト
  • 明示したいときは image_config.aspect_ratio を指定

X(Twitter)で映える比率

シーン 最適比率 理由
縦で画面占有 4:5(896×1152) タイムラインで縦領域を最大化
横の見栄え/カード連携 16:9(1344×768) プレビュー枠に最適化
ロゴ/商品/アイコン 1:1(1024×1024) 丸抜きに強い

プロンプト原則

  • キーワード羅列より“情景の文章” が有効
  • 重要要素(顔/ロゴ等)は保持条件を明記
  • 言語は ja-JP / EN / es-MX / zh-CN / hi-IN が推奨

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?