Imagen 是一种图片生成模型。它可用于为用户个人资料生成自定义头像,或将个性化视觉资源集成到现有界面流程中,以提高用户互动度。
您可以使用 Firebase AI Logic SDK从 Android 应用访问Imagen 模型。Imagen 模型可通过 Google 的任一 API 提供商使用:Gemini Developer API(建议大多数 开发者使用)和 Agent Platform Gemini API(以前称为 Vertex AI)。
使用提示进行实验
创建理想的提示通常需要多次尝试。您可以在 Google AI Studio(一种用于提示 设计和原型设计的 IDE)中使用图片提示进行实验 。如需了解有关如何改进提示的提示,请参阅 提示和图片属性指南。
设置 Firebase 项目并关联应用
按照 Firebase 文档中的步骤 将 Firebase 添加到 Android 项目。
添加 Gradle 依赖项
将以下依赖项添加到 build.gradle 文件:
dependencies {
// Import the BoM for the Firebase platform
implementation(platform("com.google.firebase:firebase-bom:34.18.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")
}
生成图片
如需在 Android 应用中生成图片,请先使用可选配置实例化 ImagenModel。
您可以使用 generationConfig 参数定义否定提示、
图片数量、输出图片宽高比、图片格式并添加
水印。您可以使用 safetySettings 参数配置
安全和人物过滤条件。
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.getInstance(GenerativeBackend.googleAI()).imagenModel( "imagen-4.0-generate-001", config, new ImagenSafetySettings( ImagenSafetyFilterLevel.BLOCK_LOW_AND_ABOVE, ImagenPersonFilterLevel.BLOCK_ALL)) );
实例化 ImagenModel 后,您可以通过调用 generateImages 生成图片:
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
ListenableFuture<ImagenGenerationResponse<ImagenInlineImage>> futureResponse = model.generateImages( "A hyper realistic picture of a t-rex with a blue bagpack in a prehistoric forest"); try { ImagenGenerationResponse<ImagenInlineImage> imageResponse = futureResponse.get(); List<ImagenInlineImage> images = null; if (imageResponse != null) { images = imageResponse.getImages(); } if (images != null && !images.isEmpty()) { ImagenInlineImage image = images.get(0); Bitmap bitmapImage = image.asBitmap(); // Use bitmapImage } } catch (ExecutionException | InterruptedException e) { e.printStackTrace(); }
使用 Imagen 修改图片
Firebase AI Logic SDK 通过 Imagen 模型提供高级图片修改功能,让您能够:
- 根据蒙版修改图片 ,包括插入 或移除对象、将图片内容扩展到原始边界之外 以及更改背景等操作。
- 自定义图片,方法是应用特定样式 (图案、纹理或艺术家风格)、专注于各种主题(例如产品、人物或动物),或遵循不同的控制条件(例如手绘草图、Canny 边缘图片或面部网格)。
模型初始化
如需使用 Imagen 编辑功能,请指定支持图片编辑的 Imagen 模型,例如 imagen-3.0-capability-001:
val imagenModel = Firebase.ai(backend = GenerativeBackend.vertexAI()) .imagenModel("imagen-3.0-capability-001")
基于蒙版的修改
借助 Imagen 的基于蒙版的修改功能,您可以通过定义要由模型操作的特定区域来修改图片。此功能支持一系列操作,包括创建和应用蒙版、插入或移除对象,以及将图片内容扩展到原始边界之外。
创建蒙版
如需执行基于蒙版的修改(例如插入或移除对象),您需要定义需要由模型修改的区域,即蒙版。
如需创建蒙版,您可以让模型使用
ImagenBackgroundMask() 或 ImagenSemanticMask() 自动生成蒙版,并传递 类
ID。
您还可以通过生成蒙版位图并将其转换为 ImagenRawMask,在屏幕上手动绘制蒙版。使用 detectDragGestures 和 Canvas,您可以在应用中使用 Jetpack Compose 实现蒙版绘制界面,如下所示:
//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 = createMaskBitmap(sourceBitmap, paths) onMaskFinalized(maskBitmap) }, ) { Text("Save mask") } } }
然后,您可以通过在画布上绘制路径来创建蒙版位图:
// import android.graphics.Color as AndroidColor // import android.graphics.Paint private fun createMaskBitmap( sourceBitmap: Bitmap, paths: SnapshotStateList<Path>, ): Bitmap { val maskBitmap = Bitmap.createBitmap(sourceBitmap.width, sourceBitmap.height, Bitmap.Config.ARGB_8888) 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 }
确保蒙版的大小与源图片的大小相同。如需了解详情,请参阅 Imagen AI 目录示例。
插入对象
您可以将新对象或内容插入现有图片,也称为修复。 模型将生成新内容并将其插入指定的蒙版区域。
如需实现此目的,请使用 editImage() 函数。您需要提供
原始图片、蒙版和描述要插入内容的文本提示
。此外,请传递 ImagenEditingConfig 对象,确保其 editMode 属性设置为 ImagenEditMode.INPAINT_INSERTION。
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( referenceImages = listOf( ImagenRawImage(originalImage.toImagenInlineImage()), mask, ), prompt = prompt, // Define the editing configuration for inpainting and insertion. config = ImagenEditingConfig(ImagenEditMode.INPAINT_INSERTION) ) return editedImage }
移除对象
借助修复功能,您可以从图片中移除不需要的对象。为此,请使用 editImage 函数。您需要提供原始图片和突出显示要移除对象的
蒙版。(可选)您可以添加文本提示来描述对象,这有助于模型准确识别对象。此外,您必须将 ImagenEditingConfig 中的 editMode 设置为 ImagenEditMode.INPAINT_REMOVAL。
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( referenceImages = listOf( ImagenRawImage(originalImage.toImagenInlineImage()), mask ), prompt = prompt, // Define the editing configuration for inpainting and removal. config = ImagenEditingConfig(ImagenEditMode.INPAINT_REMOVAL) ) return editedImage }
扩展图片内容
您可以使用 outpaintImage() 函数将图片扩展到原始边界之外,这称为 扩绘。
此函数需要原始
图片和扩展图片的必要 Dimensions。
(可选)您可以添加扩展的描述性提示,并指定
原始图片在新生成的图片中的 ImagenImagePlacement:
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 = imagenModel.outpaintImage( originalImage.toImagenInlineImage(), Dimensions(1024, 1024), prompt = prompt, newPosition = ImagenImagePlacement.LEFT_CENTER ) return editedImage }
替换背景
您可以在保留前景主题的同时替换图片的背景。为此,请使用 editImage 函数。传递原始图片、ImagenBackgroundMask 对象(包含新背景的文本提示)和 ImagenEditingConfig,并将其 editMode 属性设置为 ImagenEditMode.INPAINT_INSERTION。
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( referenceImages = listOf( ImagenRawImage(originalImage.toImagenInlineImage()), ImagenBackgroundMask(), ), prompt = prompt, config = ImagenEditingConfig(ImagenEditMode.INPAINT_INSERTION) ) return editedImage }
自定义
您可以使用 Imagen 的自定义功能 ,根据指定主题、控制条件或样式的参考图片生成或修改图片。为此,请提供文本提示以及一个或多个参考图片来引导模型。
根据主题进行自定义
您可以根据参考图片(例如产品、人物或动物)生成特定主题的新图片。只需提供文本提示和至少一张主题的参考图片即可。例如,您可以上传宠物的照片,并在完全不同的环境中生成其新图片。
为此,请使用 ImagenSubjectReference 定义主题参考,然后将其与提示一起传递给 editImage。此外,请添加指定 editSteps 数量的 ImagenEditingConfig;editSteps 值越高,通常会获得质量更好的结果:
suspend fun customizeCatImage(model: ImagenModel, referenceCatImage: Bitmap): ImagenGenerationResponse<ImagenInlineImage> { // Define the subject reference using the reference image. val subjectReference = ImagenSubjectReference( image = referenceCatImage.toImagenInlineImage(), 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( referenceImages = listOf(subjectReference), prompt = prompt, config = ImagenEditingConfig( editSteps = 50 // Number of editing steps, a higher value can improve quality ) ) return editedImage }
根据控制条件进行自定义
此技术根据控制参考图片 (例如手绘草图(“涂鸦”)、Canny 边缘图片 或面部网格)生成新图片。模型使用控制图片作为新图片布局和构图的结构指南,而文本提示则提供颜色和纹理等详细信息。
使用 ImagenControlReference 定义控制参考,并将其与提示和 ImagenEditingConfig(包含 editSteps 数量,值越高可以提高质量)一起提供给 editImage:
suspend fun customizeCatImageByControl(model: ImagenModel, referenceImage: Bitmap): ImagenGenerationResponse<ImagenInlineImage> { // Define the subject reference using the reference image. val controlReference = ImagenControlReference( image = referenceImage.toImagenInlineImage(), referenceId = 1, type = ImagenControlType.SCRIBBLE, ) val prompt = "A cat flying through outer space arranged like the scribble map[1]" val editedImage = model.editImage( referenceImages = listOf(controlReference), prompt = prompt, config = ImagenEditingConfig( editSteps = 50 ), ) return editedImage }
根据样式进行自定义
您可以生成或修改图片,以匹配参考图片中的特定样式 (例如图案、纹理或设计)。模型使用参考图片来了解所需的美感,并将其应用于文本提示中描述的新图片。例如,您可以提供一幅著名画作的图片,生成一幅采用该画作风格的猫的图片。
使用 ImagenStyleReference 定义样式参考,并将其与提示和 ImagenEditingConfig(包含 editSteps 数量,值越高可以提高质量)一起提供给 editImage:
suspend fun customizeImageByStyle(model: ImagenModel, referenceVanGoghImage: Bitmap): ImagenGenerationResponse<ImagenInlineImage> { // Define the style reference using the reference image. val styleReference = ImagenStyleReference( image = referenceVanGoghImage.toImagenInlineImage(), 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( referenceImages = listOf(styleReference), prompt = prompt, config = ImagenEditingConfig( editSteps = 50 // Number of editing steps, a higher value can improve quality ), ) return editedImage }
后续步骤
- 如需详细了解 Firebase AI Logic,请参阅 Firebase 文档。
- 探索 Android AI 示例目录。