Imagen ist ein Modell zur Bildgenerierung. Damit lassen sich benutzerdefinierte Avatare für Nutzerprofile erstellen oder personalisierte visuelle Assets in bestehende Bildschirmabläufe einbinden, um die Nutzerinteraktion zu steigern.
Sie können über das Firebase AI Logic SDK in Ihrer Android-App auf Imagen-Modelle zugreifen. Imagen-Modelle sind über beide API-Anbieter von Firebase AI Logic verfügbar: die Gemini Developer API (für die meisten Entwickler empfohlen) und Vertex AI.
Prompts ausprobieren
Das Erstellen der idealen Prompts erfordert oft mehrere Versuche. Sie können mit Bild-Prompts in Google AI Studio experimentieren, einer IDE für Prompt-Design und Prototyping. Tipps zur Verbesserung Ihrer Prompts finden Sie im Leitfaden zu Prompts und Bildattributen.

Firebase-Projekt einrichten und App verbinden
Folgen Sie der Anleitung in der Firebase-Dokumentation, um Firebase zu Ihrem Android-Projekt hinzuzufügen.
Gradle-Abhängigkeit hinzufügen
Fügen Sie der Datei build.gradle
die folgenden Abhängigkeiten hinzu:
dependencies {
// Import the BoM for the Firebase platform
implementation(platform("com.google.firebase:firebase-bom:34.4.0"))
// Add the dependency for the Firebase AI Logic library. When using the BoM,
// you don't specify versions in Firebase library dependencies
implementation("com.google.firebase:firebase-ai")
}
Bild generieren
Wenn Sie ein Bild in Ihrer Android-App generieren möchten, instanziieren Sie zuerst ein ImagenModel
mit einer optionalen Konfiguration.
Mit dem Parameter generationConfig
können Sie einen negativen Prompt, die Anzahl der Bilder, das Seitenverhältnis des Ausgabebilds und das Bildformat definieren sowie ein Wasserzeichen hinzufügen. Mit dem Parameter safetySettings
können Sie die Sicherheits- und Personenfilter konfigurieren.
Kotlin
val config = ImagenGenerationConfig {
numberOfImages = 2,
aspectRatio = ImagenAspectRatio.LANDSCAPE_16x9,
imageFormat = ImagenImageFormat.jpeg(compressionQuality = 100),
addWatermark = false
}
// Initialize the Gemini Developer API backend service
// For Vertex AI use Firebase.ai(backend = GenerativeBackend.vertexAI())
val model = Firebase.ai(backend = GenerativeBackend.googleAI()).imagenModel(
modelName = "imagen-4.0-generate-001",
generationConfig = config,
safetySettings = ImagenSafetySettings(
safetyFilterLevel = ImagenSafetyFilterLevel.BLOCK_LOW_AND_ABOVE,
personFilterLevel = ImagenPersonFilterLevel.BLOCK_ALL
)
)
Java
ImagenGenerationConfig config = new ImagenGenerationConfig.Builder()
.setNumberOfImages(2)
.setAspectRatio(ImagenAspectRatio.LANDSCAPE_16x9)
.setImageFormat(ImagenImageFormat.jpeg(100))
.setAddWatermark(false)
.build();
// For Vertex AI use Firebase.ai(backend = GenerativeBackend.vertexAI())
ImagenModelFutures model = ImagenModelFutures.from(
FirebaseAI.ai(backend = GenerativeBackend.googleAI()).imagenModel(
"imagen-4.0-generate-001",
config,
ImagenSafetySettings.builder()
.setSafetyFilterLevel(ImagenSafetyFilterLevel.BLOCK_LOW_AND_ABOVE)
.setPersonFilterLevel(ImagenPersonFilterLevel.BLOCK_ALL)
.build())
);
Sobald Ihre ImagenModel
instanziiert ist, können Sie Bilder generieren, indem Sie generateImages
aufrufen:
Kotlin
val imageResponse = model.generateImages(
prompt = "A hyper realistic picture of a t-rex with a blue bagpack in a prehistoric forest",
)
val image = imageResponse.images.first
val bitmapImage = image.asBitmap()
Java
CompletableFuture<GenerateContentResponse> futureResponse =
model.generateContent(
Content.newBuilder()
.addParts(
Part.newBuilder()
.setText("A hyper realistic picture of a t-rex with a blue bagpack in a prehistoric forest")
.build())
.build());
try {
GenerateContentResponse imageResponse = futureResponse.get();
List<GeneratedImage> images =
imageResponse
.getCandidates(0)
.getContent()
.getParts(0)
.getInlineData()
.getImagesList();
if (!images.isEmpty()) {
GeneratedImage image = images.get(0);
Bitmap bitmapImage = image.asBitmap();
// Use bitmapImage
}
} catch (ExecutionException | InterruptedException e) {
e.printStackTrace();
}
Bilder mit Imagen bearbeiten
Die Firebase AI Logic SDKs bieten erweiterte Bildbearbeitungsfunktionen über das Imagen-Modell. Damit können Sie:
- Bilder anhand von Masken bearbeiten: Dazu gehören Aktionen wie das Einfügen oder Entfernen von Objekten, das Erweitern von Bildinhalten über die ursprünglichen Grenzen hinaus und das Ändern von Hintergründen.
- Bilder anpassen – durch Anwenden bestimmter Stile (Muster, Texturen oder Künstlerstile), durch Fokussieren auf verschiedene Motive (z. B. Produkte, Personen oder Tiere) oder durch Einhalten verschiedener Steuerelemente (z. B. handgezeichnete Skizze, Canny-Edge-Bild oder Gesichts-Mesh).
Modellinitialisierung
Wenn Sie die Imagen-Bearbeitungsfunktionen verwenden möchten, geben Sie ein Imagen-Modell an, das die Bildbearbeitung unterstützt, z. B. imgen-3.0-capability-001
. Version des Modells:
val imagenModel = Firebase.ai(backend = GenerativeBackend.vertexAI())
.imagenModel("imagen-3.0-capability-001")
Maskenbasierte Bearbeitung
Mit der maskenbasierte Bearbeitung von Imagen können Bilder bearbeitet werden, indem bestimmte Bereiche für das Modell definiert werden. Diese Funktion ermöglicht eine Reihe von Aktionen, darunter das Erstellen und Anwenden von Masken, das Einfügen oder Entfernen von Objekten und das Erweitern von Bildinhalten über die ursprünglichen Grenzen hinaus.
Maske erstellen
Für die maskenbasierte Bearbeitung, z. B. zum Einfügen oder Entfernen von Objekten, müssen Sie den Bereich definieren, der vom Modell bearbeitet werden soll – die Maske.
Wenn Sie eine Maske erstellen möchten, können Sie sie vom Modell automatisch generieren lassen, indem Sie ImagenBackgroundMask()
oder ImagenSemanticMask()
verwenden und eine Klassen-ID übergeben.
Sie können die Maske auch manuell auf dem Bildschirm zeichnen, indem Sie eine Masken-Bitmap generieren und in eine ImagenRawMask
konvertieren. Mit detectDragGestures
und Canvas
können Sie in Ihrer App eine Benutzeroberfläche zum Zeichnen von Masken mit Jetpack Compose implementieren:
import androidx.compose.ui.graphics.Color as ComposeColor
[...]
@Composable
fun ImagenEditingMaskEditor(
sourceBitmap: Bitmap,
onMaskFinalized: (Bitmap) -> Unit,
) {
val paths = remember { mutableStateListOf<Path>() }
var currentPath by remember { mutableStateOf<Path?>(null) }
var scale by remember { mutableFloatStateOf(1f) }
var offsetX by remember { mutableFloatStateOf(0f) }
var offsetY by remember { mutableFloatStateOf(0f) }
Column(
modifier = Modifier.fillMaxSize(),
) {
Box(
modifier = Modifier
.fillMaxWidth()
.pointerInput(Unit) {
detectDragGestures(
onDragStart = { startOffset ->
val transformedStart = Offset(
(startOffset.x - offsetX) / scale,
(startOffset.y - offsetY) / scale,
)
currentPath = Path().apply { moveTo(transformedStart.x, transformedStart.y) }
},
onDrag = { change, _ ->
currentPath?.let {
val transformedChange = Offset(
(change.position.x - offsetX) / scale,
(change.position.y - offsetY) / scale,
)
it.lineTo(transformedChange.x, transformedChange.y)
currentPath = Path().apply { addPath(it) }
}
change.consume()
},
onDragEnd = {
currentPath?.let { paths.add(it) }
currentPath = null
},
)
},
) {
Image(
bitmap = sourceBitmap.asImageBitmap(),
contentDescription = null,
modifier = Modifier.fillMaxSize(),
contentScale = ContentScale.Fit,
)
Canvas(modifier = Modifier.fillMaxSize()) {
val canvasWidth = size.width
val canvasHeight = size.height
val bitmapWidth = sourceBitmap.width.toFloat()
val bitmapHeight = sourceBitmap.height.toFloat()
scale = min(canvasWidth / bitmapWidth, canvasHeight / bitmapHeight)
offsetX = (canvasWidth - bitmapWidth * scale) / 2
offsetY = (canvasHeight - bitmapHeight * scale) / 2
withTransform(
{
translate(left = offsetX, top = offsetY)
scale(scale, scale, pivot = Offset.Zero)
},
) {
val strokeWidth = 70f / scale
val stroke = Stroke(width = strokeWidth, cap = StrokeCap.Round, join = StrokeJoin.Round)
val pathColor = ComposeColor.White.copy(alpha = 0.5f)
paths.forEach { path ->
drawPath(path = path, color = pathColor, style = stroke)
}
currentPath?.let { path ->
drawPath(path = path, color = pathColor, style = stroke)
}
}
}
}
Button(
onClick = {
val maskBitmap = createMask(sourceBitmap, paths)
onMaskFinalized(maskBitmap)
},
) {
Text("Save mask")
}
}
}
Anschließend können Sie die Masken-Bitmap erstellen, indem Sie die Pfade auf das Canvas zeichnen:
import android.graphics.Color as AndroidColor
import android.graphics.Paint
[...]
private fun createMaskBitmap(
sourceBitmap: Bitmap,
paths: SnapshotStateList<Path>,
): Bitmap {
val maskBitmap = createBitmap(sourceBitmap.width, sourceBitmap.height)
val canvas = android.graphics.Canvas(maskBitmap)
val paint = Paint().apply {
color = AndroidColor.RED
strokeWidth = 70f
style = Paint.Style.STROKE
strokeCap = Paint.Cap.ROUND
strokeJoin = Paint.Join.ROUND
isAntiAlias = true
}
paths.forEach { path -> canvas.drawPath(path.asAndroidPath(), paint) }
return maskBitmap
}
Die Maske muss dieselbe Größe wie das Quellbild haben. Weitere Informationen finden Sie unter Imagen AI-Katalogbeispiele.
Objekte einfügen
Sie können ein neues Objekt oder einen neuen Inhalt in ein vorhandenes Bild einfügen. Das wird auch als Inpainting bezeichnet. Das Modell generiert die neuen Inhalte und fügt sie in den angegebenen maskierten Bereich ein.
Verwenden Sie dazu die Funktion editImage()
. Sie müssen das Originalbild, eine Maske und einen Text-Prompt mit einer Beschreibung der Inhalte, die Sie einfügen möchten, angeben. Übergeben Sie außerdem ein ImagenEditingConfig
-Objekt und achten Sie darauf, dass dessen editMode
-Property auf ImagenEditMode.INPAINT_INSERTION
festgelegt ist.
suspend fun insertFlowersIntoImage(
model: ImagenModel,
originalImage: Bitmap,
mask: ImagenMaskReference): ImagenGenerationResponse<ImagenInlineImage> {
val prompt = "a vase of flowers"
// Pass the original image, a mask, the prompt, and an editing configuration.
val editedImage = model.editImage(
sources = listOf(
ImagenRawImage(originalImage),
mask),
prompt = prompt,
// Define the editing configuration for inpainting and insertion.
config = ImagenEditingConfig(ImagenEditMode.INPAINT_INSERTION)
)
return editedImage
}
Objekte entfernen
Mit der Funktion „Übermalen“ können Sie unerwünschte Objekte aus einem Bild entfernen. Verwenden Sie dazu die Funktion editImage
. Sie müssen das Originalbild und eine Maske bereitstellen, die das Objekt hervorhebt, das Sie entfernen möchten. Optional können Sie einen Text-Prompt einfügen, um das Objekt zu beschreiben. Das kann dem Modell helfen, es genau zu identifizieren. Außerdem müssen Sie editMode
in ImagenEditingConfig
auf ImagenEditMode.INPAINT_REMOVAL
setzen.
suspend fun removeBallFromImage(model: ImagenModel, originalImage: Bitmap, mask: ImagenMaskReference): ImagenGenerationResponse<ImagenInlineImage> {
// Optional: provide the prompt describing the content to be removed.
val prompt = "a ball"
// Pass the original image, a mask, the prompt, and an editing configuration.
val editedImage = model.editImage(
sources = listOf(
ImagenRawImage(originalImage),
mask
),
prompt = prompt,
// Define the editing configuration for inpainting and removal.
config = ImagenEditingConfig(ImagenEditMode.INPAINT_REMOVAL)
)
return editedImage
}
Bildinhalte maximieren
Mit der Funktion outpaintImage()
können Sie ein Bild über seine ursprünglichen Grenzen hinaus erweitern. Das wird als Outpainting bezeichnet. Für diese Funktion sind das Originalbild und die erforderlichen Dimensions
des erweiterten Bildes erforderlich.
Optional können Sie einen beschreibenden Prompt für die Erweiterung einfügen und die ImagenImagePlacement
des Originalbilds im neu generierten Bild angeben:
suspend fun expandImage(originalImage: Bitmap, imagenModel: ImagenModel): ImagenGenerationResponse<ImagenInlineImage> {
// Optionally describe what should appear in the expanded area.
val prompt = "a sprawling sandy beach next to the ocean"
val editedImage = model.outpaintImage(
ImagenRawImage(originalImage),
Dimension(width, height),
prompt = prompt,
newPosition = ImagenImagePlacement.LEFT_CENTER
)
return editedImage
}
Hintergrund ersetzen
Sie können den Hintergrund eines Bildes ersetzen und dabei das Vordergrundmotiv beibehalten. Verwenden Sie dazu die Funktion editImage
. Übergeben Sie das Originalbild, ein ImagenBackgroundMask
-Objekt (mit einem Textprompt für den neuen Hintergrund) und ein ImagenEditingConfig
-Objekt, dessen editMode
-Attribut auf ImagenEditMode.INPAINT_INSERTION
festgelegt ist.
suspend fun replaceBackground(model: ImagenModel, originalImage: Bitmap): ImagenGenerationResponse<ImagenInlineImage> {
// Provide the prompt describing the new background.
val prompt = "space background"
// Pass the original image, a mask, the prompt, and an editing configuration.
val editedImage = model.editImage(
sources = listOf(
ImagenRawImage(originalImage),
ImagenBackgroundMask(),
),
prompt = prompt,
config = ImagenEditingConfig(ImagenEditMode.INPAINT_INSERTION)
)
return editedImage
}
Personalisierung
Mit der Anpassungsfunktion von Imagen können Sie Bilder anhand von Referenzbildern generieren oder bearbeiten, die ein Motiv, eine Steuerung oder einen Stil angeben. Dazu wird ein Text-Prompt zusammen mit einem oder mehreren Referenzbildern bereitgestellt, um das Modell zu steuern.
Anpassen basierend auf einem Thema
Sie können neue Bilder eines bestimmten Motivs aus einem Referenzbild generieren, z. B. eines Produkts, einer Person oder eines Tieres. Geben Sie einfach einen Text-Prompt und mindestens ein Referenzbild des Motivs an. Sie könnten beispielsweise ein Bild Ihres Haustiers hochladen und ein neues Bild davon in einer völlig anderen Umgebung generieren lassen.
Dazu definieren Sie den Themenbezug mit ImagenSubjectReference
und übergeben ihn dann zusammen mit Ihrem Prompt an editImage
. Geben Sie außerdem eine ImagenEditingConfig
an, die die Anzahl der editSteps
angibt. Ein höherer editSteps
-Wert führt in der Regel zu Ergebnissen von besserer Qualität:
suspend fun customizeCatImage(model: ImagenModel, referenceCatImage: Bitmap): ImagenGenerationResponse<ImagenInlineImage> {
// Define the subject reference using the reference image.
val subjectReference = ImagenSubjectReference(
image = referenceCatImage,
referenceID = 1,
description = "cat",
subjectType = ImagenSubjectReferenceType.ANIMAL
)
// Provide a prompt that describes the final image.
// The "[1]" links the prompt to the subject reference with ID 1.
val prompt = "A cat[1] flying through outer space"
// Use the editImage API to perform the subject customization.
val editedImage = model.editImage(
references = listOf(subjectReference),
prompt = prompt,
config = ImagenEditingConfig(
editSteps = 50 // Number of editing steps, a higher value can improve quality
)
)
return editedImage
}
Anpassung basierend auf einer Kontrollvariablen
Bei dieser Technik wird ein neues Bild auf Grundlage eines Kontrollreferenzbilds generiert, z. B. einer handgezeichneten Skizze („Scribble“), eines Canny-Edge-Bilds oder eines Gesichts-Mesh. Das Modell verwendet das Kontrollbild als strukturelle Orientierungshilfe für das Layout und die Komposition des neuen Bildes, während der Text-Prompt Details wie Farbe und Textur liefert.
Definieren Sie eine Kontrollreferenz mit ImagenControlReference
und stellen Sie sie editImage
zusammen mit einem Prompt und ImagenEditingConfig
mit der Anzahl der editSteps
zur Verfügung (ein höherer Wert kann die Qualität verbessern):
suspend fun customizeCatImageByControl(model: ImagenModel, referenceCatImage: Bitmap): ImagenGenerationResponse<ImagenInlineImage> {
// Define the subject reference using the reference image.
val controlReference = ImagenControlReference(
image = referenceImage,
referenceID = 1,
controlType = CONTROL_TYPE_SCRIBBLE
)
val prompt = "A cat flying through outer space arranged like the scribble map[1]"
val editedImage = model.editImage(
references = listOf(controlReference),
prompt = prompt,
config = ImagenEditingConfig(
editSteps = 50
)
)
return editedImage
}
Anpassung basierend auf einem Stil
Sie können ein Bild generieren oder bearbeiten, sodass es einem bestimmten Stil eines Referenzbilds entspricht, z. B. dessen Muster, Textur oder Design. Das Modell verwendet das Referenzbild, um die gewünschte Ästhetik zu verstehen, und wendet sie auf das neue Bild an, das im Text-Prompt beschrieben wird. Sie könnten beispielsweise ein Bild einer Katze im Stil eines berühmten Gemäldes erstellen, indem Sie ein Bild dieses Gemäldes bereitstellen.
Definieren Sie mit ImagenStyleReference
eine Stilreferenz und stellen Sie sie editImage
zusammen mit einem Prompt und ImagenEditingConfig
mit der Anzahl der editSteps
zur Verfügung (ein höherer Wert kann die Qualität verbessern):
suspend fun customizeImageByStyle(model: ImagenModel, referenceVanGoghImage: Bitmap): ImagenGenerationResponse<ImagenInlineImage> {
// Define the style reference using the reference image.
val styleReference = ImagenStyleReference(
image = referenceVanGoghImage,
referenceID = 1,
description = "Van Gogh style"
)
// Provide a prompt that describes the final image.
// The "1" links the prompt to the style reference with ID 1.
val prompt = "A cat flying through outer space, in the Van Gogh style[1]"
// Use the editImage API to perform the style customization.
val editedImage = model.editImage(
references = listOf(styleReference),
prompt = prompt,
config = ImagenEditingConfig(
editSteps = 50 // Number of editing steps, a higher value can improve quality
)
)
return editedImage
}