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 생성형 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 생성형 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 생성형 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 생성형 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 생성형 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 생성형 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 생성형 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 생성형 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로 인코딩된 이미지 바이트를 인라인으로 반환하는 대신 AI 생성 이미지를 Cloud Storage 버킷에 직접 쓰고 fileData.fileUri에서 객체 URI를 반환하도록 generateContent 및 streamGenerateContent 요청을 구성할 수 있습니다.

다음 Gemini 모델은 Cloud Storage 출력 지속성을 지원합니다.

기본 요건

Cloud Storage 출력 지속성으로 요청을 전송하기 전에 요청을 인증하는 주 구성원에게 대상 Cloud Storage 버킷에 대한 다음 Identity and Access Management 권한이 있는지 확인합니다.

  • storage.objects.create (스토리지 객체 생성자 역할, roles/storage.objectCreator과 같은 역할에 포함됨)

이미지를 생성하기 전에 서비스는 호출자의 사용자 인증 정보를 사용하여 대상 Cloud Storage 버킷에 대한 storage.objects.create 권한을 확인합니다. Cloud Storage 버킷이 없거나 호출자에게 쓰기 권한이 없거나 VPC 서비스 제어 경계가 쓰기를 차단하는 경우 생성 전에 요청이 실패하고 403 PERMISSION_DENIED 오류가 발생합니다.

Cloud Storage 출력으로 요청 전송

AI 생성 이미지를 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 을 사용하여 Cloud Storage에 쓰고(응답에 여러 후보가 포함된 경우 CANDIDATEINDEX 추가, 후보에 여러 이미지가 포함된 경우 IMAGE_INDEX 추가) 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): 생성된 각 AI 생성 이미지는 fileData.fileUri를 참조하는 응답 청크가 전송되기 전에 Cloud Storage에 기록됩니다.
  • 이미지가 없는 응답: 요청이 텍스트만 반환하거나 안전 필터에 의해 차단되면 Cloud Storage에 객체가 기록되지 않습니다.
  • 암호화 및 보관: 작성된 객체는 고객 관리 암호화 키 (CMEK)를 포함하여 대상 Cloud Storage 버킷의 암호화 구성을 상속하고 Cloud Storage 버킷의 수명 주기 관리 규칙을 따릅니다.

제한사항

Cloud Storage 출력에는 다음과 같은 제한사항이 있습니다.

  • 교차 프로젝트 Cloud Storage 버킷을 사용한 멀티턴 편집: 서비스는 요청을 보낸 보안 주체의 사용자 인증 정보를 사용하여 AI 생성 이미지를 작성합니다. 그러나 멀티턴 대화의 이후 요청에서 fileData.fileUri로 생성된 AI 생성 이미지를 참조하는 경우 서비스는 호출 프로젝트의 Gemini Enterprise Agent Platform 서비스 에이전트(service-PROJECT_NUMBER@gcp-sa-aiplatform.iam.gserviceaccount.com)를 사용하여 객체를 읽습니다. 대상 Cloud Storage 버킷이 다른 프로젝트에 있고 서비스 에이전트에 해당 Cloud Storage 버킷에 대한 storage.objects.get 권한이 없는 경우 원래 쓰기가 성공하더라도 후속 요청이 403 PERMISSION_DENIED 오류와 함께 실패합니다.

    AI 생성 이미지를 멀티턴 편집의 입력으로 사용하려면 서비스 에이전트에 대상 Cloud Storage 버킷에 대한 읽기 액세스 권한 (예: 스토리지 객체 뷰어 역할, roles/storage.objectViewer)을 부여합니다.

다음 단계

Gemini 이미지 생성에 대한 자세한 내용은 다음 링크를 참조하세요.