Gemini を使用した画像の生成と編集

Gemini 2.5 Flash Image(gemini-2.5-flash-image)(別名 Nano Banana)では、テキストに加えて画像を生成する機能がサポートされています。これにより、Gemini の機能が次のように拡張されます。

  • 自然言語での会話を通じて画像を繰り返し生成し、整合性とコンテキストを維持しながら画像を調整します。
  • 高品質の長いテキスト レンダリングで画像を生成します。
  • インターリーブされたテキストと画像の出力を生成します。たとえば、1 つのターンにテキストと画像を含むブログ投稿などです。これまでは、これを行うには複数のモデルを連携させる必要がありました。
  • Gemini の世界中の知識と推論機能を使用して画像を生成します。

このリリースでは、Gemini 2.5 Flash Image で 1,024 ピクセルの画像を生成できます。また、人物画像の生成もサポートされ、より柔軟で制限の少ないユーザー エクスペリエンスを提供するように更新された安全フィルタが含まれています。

次のモダリティと機能がサポートされています。

  • テキストから画像

    • プロンプトの例: 「背景に花火があるエッフェル塔の画像を生成してください」。
  • テキストから画像(テキスト レンダリング)

    • プロンプトの例: 「この巨大なテキスト投影が建物の正面にマッピングされた大きな建物のシネマティック フォトを生成してください。「Gemini 2.5 では長文のテキストを生成できるようになりました」」
  • テキスト画像変換とテキスト(インターリーブ)

    • プロンプトの例: 「パエリアのレシピをイラスト付きで生成してください。レシピの生成時に、テキストと一緒に表示する画像を作成します」。
    • プロンプトの例: 「3D アニメーション スタイルの犬の物語を生成してください。各シーンの画像を生成してください」
  • 画像とテキスト画像変換とテキスト(インターリーブ)

    • プロンプトの例:(家具付きの部屋の画像を提示して)「この部屋に合いそうなソファの色には他にどんなものがありますか?画像を更新してください」。

ベスト プラクティス

画像生成の結果を改善するには、次のベスト プラクティスを参考にしてください。

  • 具体的にする: 詳細に説明するほど、より細かく制御できます。たとえば、「ファンタジー アーマー」ではなく、「銀の葉の模様がエッチングされた、装飾的なエルフのプレート アーマー。ハイカラーとハヤブサの翼の形をした肩当て付き」とします。

  • コンテキストと意図を提供する: モデルがコンテキストを理解できるように、画像の目的を説明します。たとえば、「高級感のあるミニマリストのスキンケア ブランドのロゴを作成して」は、「ロゴを作成して」よりも効果的です。

  • 繰り返して改良: 最初の試行で完璧な画像が生成されるとは限りません。フォローアップ プロンプトを使用して、小規模な変更を加えます(例: 「照明を暖色にして」、「キャラクターの表情をもっとシリアスにして」)。

  • 手順ガイドを使用する: 複雑なシーンの場合は、リクエストを手順に分割します。たとえば、「まず、夜明けの静かで霧のかかった森の背景を作成して。次に、前景に苔むした古代の石の祭壇を追加して。最後に、祭壇の上に光る剣を 1 本置いて。」

  • 含めたくないものではなく、含めたいものを説明する: 「車なし」ではなく、「交通の気配のない、空っぽの寂れた通り」のように、ポジティブな表現でシーンを説明します。

  • カメラを制御する: カメラのビューを操作します。構図を説明する際は、「広角ショット」、「マクロショット」、「ローアングル」などの写真や映画の用語を使用します。

  • 画像のプロンプト: 「~の画像を作成して」や「~の画像を生成して」などのフレーズを使用して、意図を説明します。そうしないと、マルチモーダル モデルが画像ではなくテキストで応答する可能性があります。

制限事項:

  • 最高のパフォーマンスを実現するには、EN、es-MX、ja-JP、zh-CN、hi-IN のいずれかの言語を使用してください。

  • 画像生成では、音声や動画の入力はサポートされていません。

  • モデルは、リクエストした数の画像を正確に作成できない場合があります。

  • 最適な結果を得るには、入力に含める画像の数を最大 3 枚にしてください。

  • テキストを含む画像を生成する場合は、まずテキストを生成してから、そのテキストを含む画像を生成します。

  • 次のような状況では、画像やテキストの生成が想定どおりに機能しないことがあります。

    • モデルがテキストのみを作成する場合があります。画像が必要な場合は、リクエストで画像を明確に指定してください。例: 「作業時に画像を提供してください。」

    • モデルがテキストを画像として生成する場合があります。テキストを生成するには、テキスト出力が必要であることを明示的に指定します。たとえば、「イラスト付きの説明テキストを生成してください」などです。

    • モデルは、コンテンツの生成が完了していない場合でも、生成を停止することがあります。この場合は、もう一度お試しいただくか、別のプロンプトを使用してください。

    • プロンプトが安全でない可能性がある場合、モデルはリクエストを処理せず、安全でない画像を作成できないことを示すレスポンスを返すことがあります。この場合、FinishReasonSTOP です。

画像を生成する

以降のセクションでは、Vertex AI Studio または API を使用して画像を生成する方法について説明します。

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

コンソール

画像生成を使用するには:

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

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

Python

インストール

pip install --upgrade google-genai

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

Vertex AI で 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_VERTEXAI=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-2.5-flash-image",
    contents=("Generate an image of the Eiffel tower with fireworks in the background."),
    config=GenerateContentConfig(
        response_modalities=[Modality.TEXT, Modality.IMAGE],
        candidate_count=1,
        safety_settings=[
            {"method": "PROBABILITY"},
            {"category": "HARM_CATEGORY_DANGEROUS_CONTENT"},
            {"threshold": "BLOCK_MEDIUM_AND_ABOVE"},
        ],
    ),
)
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)))
        image.save("output_folder/example-image-eiffel-tower.png")
# 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.

Node.js

インストール

npm install @google/genai

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

Vertex AI で 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_VERTEXAI=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 で 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_VERTEXAI=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."},
    },
    "generation_config": {
      "response_modalities": ["TEXT", "IMAGE"],
      "image_config": {
        "aspect_ratio": "16:9",
      },
     },
     "safetySettings": {
      "method": "PROBABILITY",
      "category": "HARM_CATEGORY_DANGEROUS_CONTENT",
      "threshold": "BLOCK_MEDIUM_AND_ABOVE"
    },
  }' 2>/dev/null >response.json

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

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

Gemini 2.5 Flash Image では、テキスト レスポンスと画像を交互に生成できます。たとえば、生成されたレシピの各ステップがどのようなものになるかを示す画像を、そのステップのテキストに合わせて生成できます。この場合、モデルに個別のリクエストを行う必要はありません。

コンソール

テキスト レスポンスと画像が混在するコンテンツを生成するには:

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

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

Python

インストール

pip install --upgrade google-genai

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

Vertex AI で 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_VERTEXAI=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-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=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)")
# 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.

Java

Java をインストールまたは更新します。

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

Vertex AI で 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_VERTEXAI=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
      }
    }
  }
}

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. For each step, provide a title with the number of the step, an explanation, and also generate an image, generate each image in a 1:1 aspect ratio."},
    },
    "generation_config": {
      "response_modalities": ["TEXT", "IMAGE"],
      "image_config": {
        "aspect_ratio": "16:9",
      },
    },
    "safetySettings": {
      "method": "PROBABILITY",
      "category": "HARM_CATEGORY_DANGEROUS_CONTENT",
      "threshold": "BLOCK_MEDIUM_AND_ABOVE"
    },
  }' 2>/dev/null >response.json

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

画像を編集する

画像生成(gemini-2.5-flash-image)の Gemini 2.5 Flash Image では、画像の生成のほか編集もサポートされています。Gemini 2.5 Flash Image では画像の編集とマルチターン編集が改善され、より柔軟で制限の少ないユーザー エクスペリエンスを提供するように更新された安全フィルターが含まれています。

次のモダリティと機能がサポートされています。

  • 画像編集(テキストと画像による画像変換)

    • プロンプトの例: 「この画像を編集してカートゥーンのようにして」
    • プロンプトの例: [猫の画像] + [枕の画像] + 「この枕に猫のクロスステッチを作成してください」。
  • マルチターン画像編集(チャット)

    • プロンプトの例: [青い車の画像をアップロードして] 「この車をコンバーチブルにして。」

      • [モデルが同じシーンのコンバーチブルの画像を返す] 「今度は色を黄色に変えて。」
      • [モデルが黄色のコンバーチブルの画像を返す] 「スポイラーを追加して。」
      • [モデルがスポイラー付きのコンバーチブルの画像を返す]

画像を編集する

コンソール

画像を編集するには:

  1. [Vertex AI Studio] > [プロンプトを作成] を開きます。
  2. [モデルの切り替え] をクリックし、メニューから gemini-2.5-flash-image を選択します。
  3. [出力] パネルで、プルダウン メニューから [画像とテキスト] を選択します。
  4. [メディアを挿入]()をクリックし、メニューからソースを選択して、ダイアログの指示に沿って操作します。
  5. [プロンプトを入力] テキスト領域に、画像に加える編集内容を入力します。
  6. [プロンプト]()ボタンをクリックします。

Gemini は、入力された説明に基づいて、提供された画像の編集バージョンを生成します。このプロセスには数秒かかりますが、容量によっては比較的遅くなることがあります。

Python

インストール

pip install --upgrade google-genai

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

Vertex AI で 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_VERTEXAI=True

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

client = genai.Client()

# Using an image of Eiffel tower, with fireworks in the background.
image = Image.open("test_resources/example-image-eiffel-tower.png")

response = client.models.generate_content(
    model="gemini-2.5-flash-image",
    contents=[image, "Edit this image to make it look like a cartoon."],
    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)))
        image.save("output_folder/bw-example-image.png")
# Example response:
#  Here's the cartoon-style edit of the image:
#  Cartoon-style edit:
#  - Simplified the Eiffel Tower with bolder lines and slightly exaggerated proportions.
#  - Brightened and saturated the colors of the sky, fireworks, and foliage for a more vibrant, cartoonish look.
#  ....

Java

Java をインストールまたは更新します。

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

Vertex AI で 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_VERTEXAI=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.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import javax.imageio.ImageIO;

public class ImageGenMmFlashEditImageWithTextAndImage {

  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/bw-example-image.png";
    generateContent(modelId, outputFile);
  }

  // Edits an image with image and 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()) {

      byte[] localImageBytes =
          Files.readAllBytes(Paths.get("resources/example-image-eiffel-tower.png"));

      GenerateContentResponse response =
          client.models.generateContent(
              modelId,
              Content.fromParts(
                  Part.fromBytes(localImageBytes, "image/png"),
                  Part.fromText("Edit this image to make it look like a cartoon.")),
              GenerateContentConfig.builder().responseModalities("TEXT", "IMAGE").build());

      // 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:
      // No problem! Here's the image in a cartoon style...
      //
      // Content written to: resources/output/bw-example-image.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": [
        {"file_data": {
          "mime_type": "image/jpg",
          "file_uri": "<var>FILE_NAME</var>"
          }
        },
        {"text": "Convert this photo to black and white, in a cartoonish style."},
      ]

    },
    "generation_config": {
      "response_modalities": ["TEXT", "IMAGE"],
      "image_config": {
        "aspect_ratio": "16:9",
      },
    },
    "safetySettings": {
      "method": "PROBABILITY",
      "category": "HARM_CATEGORY_DANGEROUS_CONTENT",
      "threshold": "BLOCK_MEDIUM_AND_ABOVE"
    },
  }' 2>/dev/null >response.json

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

マルチターンの画像編集

Gemini 2.5 Flash Image では、マルチターン編集の改善もサポートされています。これにより、編集された画像レスポンスを受け取った後に、変更内容をモデルに送信できます。これにより、画像を会話によって編集を続行できます。

リクエスト ファイル全体のサイズは、最大 50 MB に制限することをおすすめします。

マルチターンの画像編集を試すには、Gemini 2.5 Flash Image ノートブックをお試しください。

責任ある AI

安全で責任あるエクスペリエンスを確保するため、Vertex AI の画像生成機能には多層的な安全対策が施されています。これは、露骨な性的表現、危険な表現、暴力的な表現、差別的な表現、有害な表現など、不適切なコンテンツの作成を防ぐように設計されています。

すべてのユーザーは、生成 AI の使用禁止に関するポリシーを遵守する必要があります。このポリシーでは、以下のようなコンテンツの生成が厳しく禁止されています。

  • 児童性的虐待や児童の搾取に関連している。
  • 暴力的な過激主義やテロリズムを助長している。
  • 当人の合意なく作成された親密な状況のシナリオ・画像・動画を助長している。 自傷行為を助長している。
  • 露骨な性表現を含む。
  • ヘイトスピーチに該当する。
  • ハラスメントやいじめを助長する。

不適切なプロンプトが指定された場合、モデルは画像の生成を拒否することがあります。また、プロンプトや生成されたレスポンスが安全フィルタによってブロックされることもあります。

  • モデルの拒否: プロンプトが安全でない可能性がある場合、モデルはリクエストの処理を拒否することがあります。このような場合、モデルは通常、安全でない画像を生成できないというテキスト レスポンスを返します。FinishReasonSTOP になります。
  • 安全フィルタのブロック:
    • プロンプトが安全フィルタによって有害と判断された場合、API は PromptFeedbackBlockedReason を返します。
    • レスポンスが安全フィルタによって有害な可能性があると判断された場合、API レスポンスには IMAGE_SAFETYIMAGE_PROHIBITED_CONTENT などの FinishReason が含まれます。
    • プロンプトまたはレスポンスが安全性フィルタによってブロックされた場合、finishMessage フィールドにはエラーコードの詳細が表示されます。これらのコードは、有害カテゴリにマッピングされます。
エラーコード 安全性のカテゴリ 説明
89371032
49114662
72817394
11030041
47555161
32549819
51891163
禁止コンテンツ リクエストで子供の安全に関する禁止コンテンツのリクエストを検出します。
63429089 性的 性的なコンテンツを検出します。
87332966 危険なコンテンツ 本質的に危険な可能性のあるコンテンツを検出します。
22137204 悪意のあるコンテンツ ヘイト関連のトピックやコンテンツを検出します。
49257518
65344558
著名人の安全 Google の安全性ポリシーに違反する著名人のフォトリアリスティックな表現を検出します。
14952152 その他 リクエストに関するその他の安全性に関する問題を検出します。
39322892 人物 / 顔 リクエストの設定で許可されていないときに、人物や顔を検出します。
17301594 API リクエストの設定により許可されていない場合、子ども向けコンテンツを検出します。