Gemini で画像を生成する

Gemini を使用して、テキスト プロンプトから画像を生成できます。サポートされているインターフェースには、 Google Cloud コンソールと Agent Platform API があります。

次の Gemini モデルは画像生成をサポートしています。

クリックしてサポートされているモデルを開く

Gemini モデルの機能の詳細については、Gemini モデルをご覧ください。

画像を生成

以下では、Agent Studio または API を使用して画像を生成する方法について説明します。

プロンプトのベスト プラクティスの詳細については、マルチモーダル プロンプトを設計するをご覧ください。

コンソール

Gemini で画像を生成する手順は次のとおりです。

  1. [Agent Studio] > [プロンプトを作成] を開きます。
  2. [モデルの切り替え] をクリックし、表示されたモデルのいずれかを選択します。
  3. [出力] パネルで、プルダウン メニューから [画像とテキスト] を選択します。
  4. [プロンプトを作成] テキスト領域に、生成する画像の説明を入力します。
  5. [プロンプト]()ボタンをクリックします。

Gemini は、説明に基づいて画像を生成します。このプロセスには数秒かかりますが、容量によっては比較的遅くなることがあります。

Python

インストール

pip install --upgrade google-genai

詳しくは、SDK リファレンス ドキュメントをご覧ください。

Vertex AI で Google Gen AI SDK を使用するための環境変数を設定します。

# Replace the `GOOGLE_CLOUD_PROJECT` and `GOOGLE_CLOUD_LOCATION` values
# with appropriate values for your project.
export GOOGLE_CLOUD_PROJECT=GOOGLE_CLOUD_PROJECT
export GOOGLE_CLOUD_LOCATION=global
export GOOGLE_GENAI_USE_ENTERPRISE=True

import os
from io import BytesIO

from google import genai
from google.genai.types import GenerateContentConfig, Modality
from PIL import Image

client = genai.Client()

response = client.models.generate_content(
    model="gemini-3.1-flash-image",
    contents=("Generate an image of the Eiffel tower with fireworks in the background."),
    config=GenerateContentConfig(
        response_modalities=[Modality.TEXT, Modality.IMAGE],
    ),
)
for part in response.candidates[0].content.parts:
    if part.text:
        print(part.text)
    elif part.inline_data:
        image = Image.open(BytesIO((part.inline_data.data)))
        # Ensure the output directory exists
        output_dir = "output_folder"
        os.makedirs(output_dir, exist_ok=True)
        image.save(os.path.join(output_dir, "example-image-eiffel-tower.png"))

Go

Go をインストールまたは更新する方法について学びます。

詳しくは、SDK リファレンス ドキュメントをご覧ください。

Vertex AI で Google Gen AI SDK を使用するための環境変数を設定します。

# Replace the `GOOGLE_CLOUD_PROJECT` and `GOOGLE_CLOUD_LOCATION` values
# with appropriate values for your project.
export GOOGLE_CLOUD_PROJECT=GOOGLE_CLOUD_PROJECT
export GOOGLE_CLOUD_LOCATION=global
export GOOGLE_GENAI_USE_ENTERPRISE=True

import (
	"context"
	"fmt"
	"io"
	"os"

	"google.golang.org/genai"
)

// generateMMFlashWithText demonstrates how to generate both text and image outputs.
func generateMMFlashWithText(w io.Writer) error {
	ctx := context.Background()

	client, err := genai.NewClient(ctx, &genai.ClientConfig{
		HTTPOptions: genai.HTTPOptions{APIVersion: "v1"},
	})
	if err != nil {
		return fmt.Errorf("failed to create genai client: %w", err)
	}

	modelName := "gemini-2.5-flash-image"
	contents := []*genai.Content{
		{
			Parts: []*genai.Part{
				{Text: "Generate an image of the Eiffel tower with fireworks in the background."},
			},
			Role: genai.RoleUser,
		},
	}

	resp, err := client.Models.GenerateContent(ctx,
		modelName,
		contents,
		&genai.GenerateContentConfig{
			ResponseModalities: []string{
				string(genai.ModalityText),
				string(genai.ModalityImage),
			},
			CandidateCount: int32(1),
			SafetySettings: []*genai.SafetySetting{
				{Method: genai.HarmBlockMethodProbability},
				{Category: genai.HarmCategoryDangerousContent},
				{Threshold: genai.HarmBlockThresholdBlockMediumAndAbove},
			},
		},
	)
	if err != nil {
		return fmt.Errorf("failed to generate content: %w", err)
	}

	if len(resp.Candidates) == 0 || resp.Candidates[0].Content == nil {
		return fmt.Errorf("no candidates returned")
	}
	var fileName string
	for _, part := range resp.Candidates[0].Content.Parts {
		if part.Text != "" {
			fmt.Fprintln(w, part.Text)
		} else if part.InlineData != nil {
			fileName = "example-image-eiffel-tower.png"
			if err := os.WriteFile(fileName, part.InlineData.Data, 0o644); err != nil {
				return fmt.Errorf("failed to save image: %w", err)
			}
		}
	}
	fmt.Fprintln(w, fileName)

	// Example response:
	// I will generate an image of the Eiffel Tower at night, with a vibrant display of
	// colorful fireworks exploding in the dark sky behind it.
	// ....
	return nil
}

Node.js

インストール

npm install @google/genai

詳しくは、SDK リファレンス ドキュメントをご覧ください。

Vertex AI で Google Gen AI SDK を使用するための環境変数を設定します。

# Replace the `GOOGLE_CLOUD_PROJECT` and `GOOGLE_CLOUD_LOCATION` values
# with appropriate values for your project.
export GOOGLE_CLOUD_PROJECT=GOOGLE_CLOUD_PROJECT
export GOOGLE_CLOUD_LOCATION=global
export GOOGLE_GENAI_USE_ENTERPRISE=True

const fs = require('fs');
const {GoogleGenAI, Modality} = require('@google/genai');

const GOOGLE_CLOUD_PROJECT = process.env.GOOGLE_CLOUD_PROJECT;
const GOOGLE_CLOUD_LOCATION =
  process.env.GOOGLE_CLOUD_LOCATION || 'us-central1';

async function generateImage(
  projectId = GOOGLE_CLOUD_PROJECT,
  location = GOOGLE_CLOUD_LOCATION
) {
  const client = new GoogleGenAI({
    vertexai: true,
    project: projectId,
    location: location,
  });

  const response = await client.models.generateContentStream({
    model: 'gemini-2.5-flash-image',
    contents:
      'Generate an image of the Eiffel tower with fireworks in the background.',
    config: {
      responseModalities: [Modality.TEXT, Modality.IMAGE],
    },
  });

  const generatedFileNames = [];
  let imageIndex = 0;

  for await (const chunk of response) {
    const text = chunk.text;
    const data = chunk.data;
    if (text) {
      console.debug(text);
    } else if (data) {
      const outputDir = 'output-folder';
      if (!fs.existsSync(outputDir)) {
        fs.mkdirSync(outputDir, {recursive: true});
      }
      const fileName = `${outputDir}/generate_content_streaming_image_${imageIndex++}.png`;
      console.debug(`Writing response image to file: ${fileName}.`);
      try {
        fs.writeFileSync(fileName, data);
        generatedFileNames.push(fileName);
      } catch (error) {
        console.error(`Failed to write image file ${fileName}:`, error);
      }
    }
  }

  // Example response:
  //  I will generate an image of the Eiffel Tower at night, with a vibrant display of
  //  colorful fireworks exploding in the dark sky behind it. The tower will be
  //  illuminated, standing tall as the focal point of the scene, with the bursts of
  //  light from the fireworks creating a festive atmosphere.

  return generatedFileNames;
}

Java

Java をインストールまたは更新する方法について学びます。

詳しくは、SDK リファレンス ドキュメントをご覧ください。

Vertex AI で Google Gen AI SDK を使用するための環境変数を設定します。

# Replace the `GOOGLE_CLOUD_PROJECT` and `GOOGLE_CLOUD_LOCATION` values
# with appropriate values for your project.
export GOOGLE_CLOUD_PROJECT=GOOGLE_CLOUD_PROJECT
export GOOGLE_CLOUD_LOCATION=global
export GOOGLE_GENAI_USE_ENTERPRISE=True


import com.google.genai.Client;
import com.google.genai.types.Blob;
import com.google.genai.types.Candidate;
import com.google.genai.types.Content;
import com.google.genai.types.GenerateContentConfig;
import com.google.genai.types.GenerateContentResponse;
import com.google.genai.types.Part;
import com.google.genai.types.SafetySetting;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.imageio.ImageIO;

public class ImageGenMmFlashWithText {

  public static void main(String[] args) throws IOException {
    // TODO(developer): Replace these variables before running the sample.
    String modelId = "gemini-2.5-flash-image";
    String outputFile = "resources/output/example-image-eiffel-tower.png";
    generateContent(modelId, outputFile);
  }

  // Generates an image with text input
  public static void generateContent(String modelId, String outputFile) throws IOException {
    // Client Initialization. Once created, it can be reused for multiple requests.
    try (Client client = Client.builder().location("global").vertexAI(true).build()) {

      GenerateContentConfig contentConfig =
          GenerateContentConfig.builder()
              .responseModalities("TEXT", "IMAGE")
              .candidateCount(1)
              .safetySettings(
                  SafetySetting.builder()
                      .method("PROBABILITY")
                      .category("HARM_CATEGORY_DANGEROUS_CONTENT")
                      .threshold("BLOCK_MEDIUM_AND_ABOVE")
                      .build())
              .build();

      GenerateContentResponse response =
          client.models.generateContent(
              modelId,
              "Generate an image of the Eiffel tower with fireworks in the background.",
              contentConfig);

      // Get parts of the response
      List<Part> parts =
          response
              .candidates()
              .flatMap(candidates -> candidates.stream().findFirst())
              .flatMap(Candidate::content)
              .flatMap(Content::parts)
              .orElse(new ArrayList<>());

      // For each part print text if present, otherwise read image data if present and
      // write it to the output file
      for (Part part : parts) {
        if (part.text().isPresent()) {
          System.out.println(part.text().get());
        } else if (part.inlineData().flatMap(Blob::data).isPresent()) {
          BufferedImage image =
              ImageIO.read(new ByteArrayInputStream(part.inlineData().flatMap(Blob::data).get()));
          ImageIO.write(image, "png", new File(outputFile));
        }
      }

      System.out.println("Content written to: " + outputFile);
      // Example response:
      // Here is the Eiffel Tower with fireworks in the background...
      //
      // Content written to: resources/output/example-image-eiffel-tower.png
    }
  }
}

REST

ターミナルで次のコマンドを実行して、このファイルを現在のディレクトリに作成または上書きします。

curl -X POST \
  -H "Authorization: Bearer $(gcloud auth print-access-token)" \
  -H "Content-Type: application/json" \
  https://${API_ENDPOINT}:generateContent \
  -d '{
    "contents": {
      "role": "USER",
      "parts": [
        {
          "text": "Create a tutorial explaining how to make a peanut butter and jelly sandwich in three easy steps."
        }
      ]
    },
    "generationConfig": {
      "responseModalities": ["TEXT", "IMAGE"],
      "imageConfig": {
        "aspectRatio": "16:9",
      },
     },
     "safetySettings": {
      "method": "PROBABILITY",
      "category": "HARM_CATEGORY_DANGEROUS_CONTENT",
      "threshold": "BLOCK_MEDIUM_AND_ABOVE"
    },
  }' 2>/dev/null >response.json

Gemini は、説明に基づいて画像を生成します。このプロセスには数秒かかりますが、容量によっては比較的遅くなることがあります。

インターリーブされた画像とテキストを生成する

Gemini を使用して、テキスト レスポンスとインターリーブ画像を生成できます。たとえば、生成されたレシピの各ステップの画像を、モデルに個別のリクエストを行うことなく生成できます。

次の Gemini モデルは、インターリーブ画像とテキストの生成をサポートしています。

クリックしてサポートされているモデルを開く

コンソール

テキスト レスポンスとインターリーブ画像を生成するには、次の操作を行います。

  1. [Agent Studio] > [プロンプトを作成] を開きます。
  2. [モデルの切り替え] をクリックし、表示されたモデルのいずれかを選択します。
  3. [出力] パネルで、プルダウン メニューから [画像とテキスト] を選択します。
  4. [プロンプトを作成] テキスト領域に、生成する画像の説明を入力します。たとえば、「ピーナッツ バターとジャムのサンドイッチを 3 つのステップで作る方法を説明するチュートリアルを作成します。各ステップについて、ステップの番号と説明を含むタイトルを付け、画像も生成してください。各画像の縦横比は 1:1 にしてください。」
  5. [プロンプト]()ボタンをクリックします。

Gemini は、説明に基づいてレスポンスを生成します。このプロセスには数秒かかりますが、容量によっては比較的遅くなることがあります。

Python

インストール

pip install --upgrade google-genai

詳しくは、SDK リファレンス ドキュメントをご覧ください。

Vertex AI で Google Gen AI SDK を使用するための環境変数を設定します。

# Replace the `GOOGLE_CLOUD_PROJECT` and `GOOGLE_CLOUD_LOCATION` values
# with appropriate values for your project.
export GOOGLE_CLOUD_PROJECT=GOOGLE_CLOUD_PROJECT
export GOOGLE_CLOUD_LOCATION=global
export GOOGLE_GENAI_USE_ENTERPRISE=True

from google import genai
from google.genai.types import GenerateContentConfig, Modality
from PIL import Image
from io import BytesIO

client = genai.Client()

response = client.models.generate_content(
    model="gemini-3.1-flash-image",
    contents=(
        "Generate an illustrated recipe for a paella."
        "Create images to go alongside the text as you generate the recipe"
    ),
    config=GenerateContentConfig(response_modalities=[Modality.TEXT, Modality.IMAGE]),
)
with open("output_folder/paella-recipe.md", "w") as fp:
    for i, part in enumerate(response.candidates[0].content.parts):
        if part.text is not None:
            fp.write(part.text)
        elif part.inline_data is not None:
            image = Image.open(BytesIO((part.inline_data.data)))
            image.save(f"output_folder/example-image-{i+1}.png")
            fp.write(f"![image](example-image-{i+1}.png)")

Java

Java をインストールまたは更新する方法について学びます。

詳しくは、SDK リファレンス ドキュメントをご覧ください。

Vertex AI で Google Gen AI SDK を使用するための環境変数を設定します。

# Replace the `GOOGLE_CLOUD_PROJECT` and `GOOGLE_CLOUD_LOCATION` values
# with appropriate values for your project.
export GOOGLE_CLOUD_PROJECT=GOOGLE_CLOUD_PROJECT
export GOOGLE_CLOUD_LOCATION=global
export GOOGLE_GENAI_USE_ENTERPRISE=True


import com.google.genai.Client;
import com.google.genai.types.Blob;
import com.google.genai.types.Candidate;
import com.google.genai.types.Content;
import com.google.genai.types.GenerateContentConfig;
import com.google.genai.types.GenerateContentResponse;
import com.google.genai.types.Part;
import java.awt.image.BufferedImage;
import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.imageio.ImageIO;

public class ImageGenMmFlashTextAndImageWithText {

  public static void main(String[] args) throws IOException {
    // TODO(developer): Replace these variables before running the sample.
    String modelId = "gemini-2.5-flash-image";
    String outputFile = "resources/output/paella-recipe.md";
    generateContent(modelId, outputFile);
  }

  // Generates text and image with text input
  public static void generateContent(String modelId, String outputFile) throws IOException {
    // Client Initialization. Once created, it can be reused for multiple requests.
    try (Client client = Client.builder().location("global").vertexAI(true).build()) {

      GenerateContentResponse response =
          client.models.generateContent(
              modelId,
              Content.fromParts(
                  Part.fromText("Generate an illustrated recipe for a paella."),
                  Part.fromText(
                      "Create images to go alongside the text as you generate the recipe.")),
              GenerateContentConfig.builder().responseModalities("TEXT", "IMAGE").build());

      try (BufferedWriter writer = new BufferedWriter(new FileWriter(outputFile))) {

        // Get parts of the response
        List<Part> parts =
            response
                .candidates()
                .flatMap(candidates -> candidates.stream().findFirst())
                .flatMap(Candidate::content)
                .flatMap(Content::parts)
                .orElse(new ArrayList<>());

        int index = 1;
        // For each part print text if present, otherwise read image data if present and
        // write it to the output file
        for (Part part : parts) {
          if (part.text().isPresent()) {
            writer.write(part.text().get());
          } else if (part.inlineData().flatMap(Blob::data).isPresent()) {
            BufferedImage image =
                ImageIO.read(new ByteArrayInputStream(part.inlineData().flatMap(Blob::data).get()));
            ImageIO.write(
                image, "png", new File("resources/output/example-image-" + index + ".png"));
            writer.write("![image](example-image-" + index + ".png)");
          }
          index++;
        }

        System.out.println("Content written to: " + outputFile);

        // Example response:
        // A markdown page for a Paella recipe(`paella-recipe.md`) has been generated.
        // It includes detailed steps and several images illustrating the cooking process.
        //
        // Content written to:  resources/output/paella-recipe.md
      }
    }
  }
}

Go

Go をインストールまたは更新する方法について学びます。

詳しくは、SDK リファレンス ドキュメントをご覧ください。

Vertex AI で Google Gen AI SDK を使用するための環境変数を設定します。

# Replace the `GOOGLE_CLOUD_PROJECT` and `GOOGLE_CLOUD_LOCATION` values
# with appropriate values for your project.
export GOOGLE_CLOUD_PROJECT=GOOGLE_CLOUD_PROJECT
export GOOGLE_CLOUD_LOCATION=global
export GOOGLE_GENAI_USE_ENTERPRISE=True

import (
	"context"
	"fmt"
	"io"
	"os"
	"path/filepath"

	"google.golang.org/genai"
)

// generateMMFlashTxtImgWithText demonstrates how to generate an illustrated recipe
// combining text and image outputs into a markdown file.
func generateMMFlashTxtImgWithText(w io.Writer) error {
	ctx := context.Background()

	client, err := genai.NewClient(ctx, &genai.ClientConfig{
		HTTPOptions: genai.HTTPOptions{APIVersion: "v1"},
	})
	if err != nil {
		return fmt.Errorf("failed to create genai client: %w", err)
	}

	modelName := "gemini-2.5-flash-image"
	contents := []*genai.Content{
		{
			Parts: []*genai.Part{
				{Text: "Generate an illustrated recipe for a paella. " +
					"Create images to go alongside the text as you generate the recipe."},
			},
			Role: genai.RoleUser,
		},
	}

	resp, err := client.Models.GenerateContent(ctx,
		modelName,
		contents,
		&genai.GenerateContentConfig{
			ResponseModalities: []string{
				string(genai.ModalityText),
				string(genai.ModalityImage),
			},
			CandidateCount: int32(1),
		},
	)
	if err != nil {
		return fmt.Errorf("failed to generate content: %w", err)
	}

	if len(resp.Candidates) == 0 || resp.Candidates[0].Content == nil {
		return fmt.Errorf("no candidates returned")
	}

	outputFolder := ""

	// Create the markdown file
	mdFile := filepath.Join(outputFolder, "paella-recipe.md")
	fp, err := os.Create(mdFile)
	if err != nil {
		return fmt.Errorf("failed to create markdown file: %w", err)
	}
	defer fp.Close()

	for i, part := range resp.Candidates[0].Content.Parts {
		if part.Text != "" {
			if _, err := fp.WriteString(part.Text); err != nil {
				return fmt.Errorf("failed to write text: %w", err)
			}
		} else if part.InlineData != nil {
			imgFile := filepath.Join(outputFolder, fmt.Sprintf("example-image-%d.png", i+1))
			if err := os.WriteFile(imgFile, part.InlineData.Data, 0644); err != nil {
				return fmt.Errorf("failed to save image: %w", err)
			}
			if _, err := fp.WriteString(fmt.Sprintf("![image](%s)", filepath.Base(imgFile))); err != nil {
				return fmt.Errorf("failed to write image reference: %w", err)
			}
		}
	}

	fmt.Fprintln(w, mdFile)

	// Example response:
	//  A markdown page for a Paella recipe (`paella-recipe.md`) has been generated.
	//  It includes detailed steps and several images illustrating the cooking process.
	return nil
}

Node.js

インストール

npm install @google/genai

詳しくは、SDK リファレンス ドキュメントをご覧ください。

Vertex AI で Google Gen AI SDK を使用するための環境変数を設定します。

# Replace the `GOOGLE_CLOUD_PROJECT` and `GOOGLE_CLOUD_LOCATION` values
# with appropriate values for your project.
export GOOGLE_CLOUD_PROJECT=GOOGLE_CLOUD_PROJECT
export GOOGLE_CLOUD_LOCATION=global
export GOOGLE_GENAI_USE_ENTERPRISE=True

const fs = require('fs');
const {GoogleGenAI, Modality} = require('@google/genai');

const GOOGLE_CLOUD_PROJECT = process.env.GOOGLE_CLOUD_PROJECT;
const GOOGLE_CLOUD_LOCATION =
  process.env.GOOGLE_CLOUD_LOCATION || 'us-central1';

async function savePaellaRecipe(response) {
  const parts = response.candidates[0].content.parts;

  let mdText = '';
  const outputDir = 'output-folder';

  for (let i = 0; i < parts.length; i++) {
    const part = parts[i];

    if (part.text) {
      mdText += part.text + '\n';
    } else if (part.inlineData) {
      if (!fs.existsSync(outputDir)) {
        fs.mkdirSync(outputDir, {recursive: true});
      }
      const imageBytes = Buffer.from(part.inlineData.data, 'base64');
      const imagePath = `example-image-${i + 1}.png`;
      const saveImagePath = `${outputDir}/${imagePath}`;

      fs.writeFileSync(saveImagePath, imageBytes);
      mdText += `![image](./${imagePath})\n`;
    }
  }
  const mdFile = `${outputDir}/paella-recipe.md`;

  fs.writeFileSync(mdFile, mdText);
  console.log(`Saved recipe to: ${mdFile}`);
}

async function generateImage(
  projectId = GOOGLE_CLOUD_PROJECT,
  location = GOOGLE_CLOUD_LOCATION
) {
  const client = new GoogleGenAI({
    vertexai: true,
    project: projectId,
    location: location,
  });

  const response = await client.models.generateContent({
    model: 'gemini-2.5-flash-image',
    contents:
      'Generate an illustrated recipe for a paella. Create images to go alongside the text as you generate the recipe',
    config: {
      responseModalities: [Modality.TEXT, Modality.IMAGE],
    },
  });
  console.log(response);

  await savePaellaRecipe(response);

  return response;
}
// Example response:
//  A markdown page for a Paella recipe(`paella-recipe.md`) has been generated.
//  It includes detailed steps and several images illustrating the cooking process.

REST

ターミナルで次のコマンドを実行して、このファイルを現在のディレクトリに作成または上書きします。

curl -X POST \
  -H "Authorization: Bearer $(gcloud auth print-access-token)" \
  -H "Content-Type: application/json" \
  https://${API_ENDPOINT}:generateContent \
  -d '{
    "contents": {
      "role": "USER",
      "parts": [
        {
          "text": "Generate an illustrated recipe for a paella. Create images to
          go alongside the text as you generate the recipe."
        }
      ]
    },
    "generationConfig": {
      "responseModalities": ["TEXT", "IMAGE"],
      "imageConfig": {
        "aspectRatio": "16:9",
      },
    },
    "safetySettings": {
      "method": "PROBABILITY",
      "category": "HARM_CATEGORY_DANGEROUS_CONTENT",
      "threshold": "BLOCK_MEDIUM_AND_ABOVE"
    },
  }' 2>/dev/null >response.json

Gemini は、説明に基づいて画像を生成します。このプロセスには数秒かかりますが、容量によっては比較的遅くなることがあります。

生成された画像を Cloud Storage に保存する

レスポンスで未加工の base64 エンコードされた画像バイトをインラインで返す代わりに、生成画像を Cloud Storage バケットに直接書き込み、オブジェクト URI を fileData.fileUri で返すように generateContent リクエストと streamGenerateContent リクエストを構成できます。

次の Gemini モデルは、Cloud Storage 出力の永続性をサポートしています。

前提条件

Cloud Storage 出力の永続性を使用してリクエストを送信する前に、リクエストを認証するプリンシパルに、宛先の Cloud Storage バケットに対する次の Identity and Access Management 権限があることを確認します。

  • storage.objects.create(Storage オブジェクト作成者ロール roles/storage.objectCreator などのロールに含まれます)

画像を生成する前に、サービスは呼び出し元の認証情報を使用して、ターゲット Cloud Storage バケットに対する storage.objects.create 権限を確認します。Cloud Storage バケットが存在しない場合、呼び出し元に書き込み権限がない場合、または VPC Service Controls の境界が書き込みをブロックしている場合、リクエストは生成前に失敗し、403 PERMISSION_DENIED エラーが発生します。

Cloud Storage 出力を含むリクエストを送信する

生成された画像を Cloud Storage に直接書き込むには、generateContent リクエストまたは streamGenerateContent リクエストで次の両方のフィールドを構成します。

  • outputConfig.outputUriPrefix を宛先の Cloud Storage バケットまたはフォルダの接頭辞(例: gs://BUCKET_NAME/PREFIX/)に設定します。
  • generationConfig.responseFormat[].image.delivery を "URI" に設定します。

次の REST リクエストは、画像を生成して Cloud Storage バケットに直接書き込みます。

curl -X POST \
  -H "Authorization: Bearer $(gcloud auth print-access-token)" \
  -H "Content-Type: application/json" \
  "https://aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/global/publishers/google/models/gemini-nano-banana-2.1:generateContent" \
  -d '{
    "contents": [
      {
        "role": "USER",
        "parts": [
          {
            "text": "Create an architectural rendering of a sustainable glass greenhouse in alpine snow."
          }
        ]
      }
    ],
    "generationConfig": {
      "responseModalities": ["TEXT", "IMAGE"],
      "responseFormat": [
        {
          "image": {
            "delivery": "URI"
          }
        }
      ]
    },
    "outputConfig": {
      "outputUriPrefix": "gs://BUCKET_NAME/PREFIX/"
    }
  }'

次のように置き換えます。

  • PROJECT_ID: 実際の Google Cloud プロジェクト ID。
  • BUCKET_NAME: 宛先の Cloud Storage バケットの名前。
  • PREFIX: Cloud Storage バケット内のオプションのフォルダパス接頭辞(例: outputs)。

このサービスは、生成された各画像部分を、命名パターン gs://BUCKETNAME/PREFIX/imageGENERATIONID.EXTENSION(レスポンスに複数の候補が含まれている場合は CANDIDATEINDEX、候補に複数の画像が含まれている場合は IMAGE_INDEX を追加)を使用して Cloud Storage に書き込み、fileData で URI を返します。

{
  "candidates": [
    {
      "content": {
        "role": "model",
        "parts": [
          {
            "fileData": {
              "mimeType": "image/png",
              "fileUri": "gs://my-bucket/outputs/image_1234567890.png"
            }
          }
        ]
      }
    }
  ]
}

Cloud Storage 出力配信を構成すると、サービスはレスポンスを次のように処理します。

  • テキストと画像の混合レスポンス: TEXT レスポンスと IMAGE レスポンスのテキスト部分は、parts[].text でインラインのままになります。生成された画像部分のみが Cloud Storage に書き込まれ、parts[].fileData オブジェクトとして返されます。
  • 思考画像: generationConfig.thinkingConfig.includeThoughts が true に設定されている場合、中間思考画像(parts[].thought: true)も thoughtimageGENERATION_ID 接頭辞を使用して Cloud Storage に書き込まれ、parts[].fileData オブジェクトとして返されます。
  • ストリーミング レスポンス(streamGenerateContent): 生成された各画像は、 fileData.fileUri を参照するレスポンス チャンクが送信される前に Cloud Storage に書き込まれます。
  • 画像なしのレスポンス: リクエストがテキストのみを返す場合や、安全フィルタによってブロックされた場合、Cloud Storage にオブジェクトは書き込まれません。
  • 暗号化と保持: 書き込まれたオブジェクトは、顧客管理の暗号鍵(CMEK)を含む宛先 Cloud Storage バケットの暗号化構成を継承し、Cloud Storage バケットのライフサイクル管理ルールに従います。

制限事項

Cloud Storage 出力には次の制限があります。

  • プロジェクト間の Cloud Storage バケットを使用したマルチターン編集: サービスは、リクエストを送信したプリンシパルの認証情報を使用して、生成画像を書き込みます。ただし、マルチターン会話の後のリクエストで、生成された画像を fileData.fileUri で参照すると、サービスは呼び出し元プロジェクトの Gemini Enterprise Agent Platform サービス エージェント(service-PROJECT_NUMBER@gcp-sa-aiplatform.iam.gserviceaccount.com)を使用してオブジェクトを読み取ります。宛先の Cloud Storage バケットが別のプロジェクトにあり、サービス エージェントにその Cloud Storage バケットに対する storage.objects.get 権限がない場合、元の書き込みが成功しても、フォローアップ リクエストは 403 PERMISSION_DENIED エラーで失敗します。

    生成画像をマルチターン編集の入力として使用するには、宛先 Cloud Storage バケットに対する読み取りアクセス権(ストレージ オブジェクト閲覧者ロール roles/storage.objectViewer など)をサービス エージェントに付与します。

次のステップ

Gemini の画像生成の詳細については、次のリンクをご覧ください。