Imagen 是一种图片生成模型。它可用于为用户个人资料生成自定义头像,或将个性化视觉资源集成到现有界面流程中,以提高用户互动度。
您可以使用 Firebase AI Logic SDK从 Android 应用访问Imagen 模型。Imagen 模型可通过以下两种 Firebase AI Logic API 提供商使用:Gemini Developer 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.11.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 示例目录。