Imagen là một mô hình tạo hình ảnh. Bạn có thể dùng mô hình này để tạo hình đại diện tuỳ chỉnh cho hồ sơ người dùng hoặc để tích hợp các thành phần hình ảnh được cá nhân hoá vào luồng màn hình hiện có nhằm tăng mức độ tương tác của người dùng.
Bạn có thể truy cập vào các mô hình Imagen từ ứng dụng Android bằng SDK Firebase AI Logic. Bạn có thể sử dụng các mô hình Imagen bằng cả hai nhà cung cấp Firebase AI Logic API: Gemini Developer API (nên dùng cho hầu hết nhà phát triển) và Vertex AI.
Thử nghiệm với câu lệnh
Bạn thường phải thử nhiều lần mới tạo được câu lệnh lý tưởng. Bạn có thể thử nghiệm với câu lệnh hình ảnh trong Google AI Studio, một IDE để thiết kế và tạo nguyên mẫu câu lệnh. Để biết các mẹo về cách cải thiện câu lệnh, hãy xem hướng dẫn về câu lệnh và thuộc tính hình ảnh.
Thiết lập dự án Firebase và kết nối ứng dụng
Làm theo các bước trong tài liệu về Firebase để thêm Firebase vào dự án Android.
Thêm phần phụ thuộc vào Gradle
Thêm các phần phụ thuộc sau vào tệp 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")
}
Tạo hình ảnh
Để tạo hình ảnh trong ứng dụng Android, hãy bắt đầu bằng cách tạo thực thể ImagenModel với một cấu hình không bắt buộc.
Bạn có thể sử dụng tham số generationConfig để xác định câu lệnh phủ định,
số lượng hình ảnh, tỷ lệ khung hình của hình ảnh đầu ra, định dạng hình ảnh và thêm
hình mờ. Bạn có thể sử dụng tham số safetySettings để định cấu hình bộ lọc an toàn và bộ lọc người.
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)) );
Sau khi tạo thực thể ImagenModel, bạn có thể tạo hình ảnh bằng cách gọi 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(); }
Chỉnh sửa hình ảnh bằng Imagen
SDK Firebase AI Logic cung cấp các tính năng chỉnh sửa hình ảnh nâng cao thông qua mô hình Imagen, cho phép bạn:
- Chỉnh sửa hình ảnh dựa trên mặt nạ, bao gồm các thao tác như chèn hoặc xoá đối tượng, mở rộng nội dung hình ảnh vượt ra ngoài ranh giới ban đầu và thay đổi nền.
- Tuỳ chỉnh hình ảnh thông qua việc áp dụng các kiểu cụ thể (mẫu, kết cấu hoặc kiểu của nghệ sĩ), bằng cách tập trung vào nhiều đối tượng (chẳng hạn như sản phẩm, người hoặc động vật) hoặc bằng cách tuân thủ các chế độ kiểm soát khác nhau (chẳng hạn như bản phác thảo vẽ tay, hình ảnh cạnh Canny hoặc lưới khuôn mặt).
Khởi chạy mô hình
Để sử dụng các tính năng chỉnh sửa của Imagen, hãy chỉ định một mô hình Imagen hỗ trợ chỉnh sửa hình ảnh, chẳng hạn như imagen-3.0-capability-001:
val imagenModel = Firebase.ai(backend = GenerativeBackend.vertexAI()) .imagenModel("imagen-3.0-capability-001")
Chỉnh sửa dựa trên mặt nạ
Tính năng chỉnh sửa dựa trên mặt nạ của Imagen cho phép sửa đổi hình ảnh bằng cách xác định các vùng cụ thể để mô hình thao tác. Tính năng này cho phép thực hiện một loạt thao tác, bao gồm tạo và áp dụng mặt nạ, chèn hoặc xoá đối tượng và mở rộng nội dung hình ảnh vượt ra ngoài ranh giới ban đầu.
Tạo mặt nạ
Để thực hiện chỉnh sửa dựa trên mặt nạ, chẳng hạn như chèn hoặc xoá đối tượng, bạn cần xác định vùng cần chỉnh sửa bằng mô hình, tức là mặt nạ.
Để tạo mặt nạ, bạn có thể để mô hình tự động tạo mặt nạ bằng cách sử dụng
ImagenBackgroundMask() hoặc ImagenSemanticMask(), truyền mã
lớp.
Bạn cũng có thể vẽ mặt nạ theo cách thủ công trên màn hình bằng cách tạo một bitmap mặt nạ và chuyển đổi bitmap đó thành ImagenRawMask. Bằng cách sử dụng detectDragGestures và Canvas, bạn có thể triển khai giao diện người dùng vẽ mặt nạ bằng Jetpack Compose trong ứng dụng như sau:
//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") } } }
Sau đó, bạn có thể tạo bitmap mặt nạ bằng cách vẽ các đường dẫn trên canvas:
// 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 }
Đảm bảo mặt nạ có cùng kích thước với hình ảnh nguồn. Xem Mẫu danh mục AI Imagen để biết thêm thông tin chi tiết.
Chèn đối tượng
Bạn có thể chèn một đối tượng hoặc nội dung mới vào hình ảnh hiện có, còn gọi là inpainting. Mô hình sẽ tạo và chèn nội dung mới vào vùng được che phủ đã chỉ định.
Để thực hiện việc này, hãy sử dụng hàm editImage(). Bạn cần cung cấp hình ảnh gốc, mặt nạvà câu lệnh dạng văn bản mô tả nội dung bạn muốn chèn. Ngoài ra, hãy truyền đối tượng ImagenEditingConfig, đảm bảo thuộc tính editMode của đối tượng này được đặt thành 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 }
Xoá đối tượng
Tính năng inpainting cho phép bạn xoá các đối tượng không mong muốn khỏi hình ảnh. Để thực hiện việc này, hãy sử dụng hàm editImage. Bạn cần cung cấp hình ảnh gốc và a
mặt nạ làm nổi bật đối tượng bạn muốn
xoá. Bạn có thể đưa vào câu lệnh dạng văn bản để mô tả đối tượng (không bắt buộc). Câu lệnh này có thể hỗ trợ mô hình xác định chính xác. Ngoài ra, bạn phải đặt editMode trong ImagenEditingConfig thành 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 }
Mở rộng nội dung hình ảnh
Bạn có thể mở rộng hình ảnh vượt ra ngoài ranh giới ban đầu, được gọi là outpainting, bằng cách sử dụng hàm outpaintImage(). Hàm này yêu cầu hình ảnh gốc
và Dimensions cần thiết của hình ảnh được mở rộng.
Bạn có thể đưa vào câu lệnh mô tả để mở rộng và chỉ định
the ImagenImagePlacement của hình ảnh gốc trong
hình ảnh mới được tạo (không bắt buộc):
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 }
Thay thế nền
Bạn có thể thay thế nền của hình ảnh trong khi vẫn giữ nguyên đối tượng ở tiền cảnh. Để thực hiện việc này, hãy sử dụng hàm editImage. Truyền hình ảnh gốc, đối tượng ImagenBackgroundMask (chứa câu lệnh dạng văn bản cho nền mới) và ImagenEditingConfig với thuộc tính editMode được đặt thành 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 }
Tùy chỉnh
Bạn có thể sử dụng tính năng tùy chỉnh của Imagen để tạo hoặc chỉnh sửa hình ảnh dựa trên hình ảnh tham khảo chỉ định đối tượng, chế độ kiểm soát hoặc kiểu. Để thực hiện việc này, hãy cung cấp câu lệnh dạng văn bản cùng với một hoặc nhiều hình ảnh tham khảo để hướng dẫn mô hình.
Tuỳ chỉnh dựa trên đối tượng
Bạn có thể tạo hình ảnh mới về một đối tượng cụ thể từ hình ảnh tham khảo (ví dụ: sản phẩm, người hoặc động vật). Chỉ cần cung cấp câu lệnh dạng văn bản và ít nhất một hình ảnh tham khảo về đối tượng. Ví dụ: bạn có thể tải ảnh thú cưng lên và tạo hình ảnh mới về thú cưng đó trong một môi trường hoàn toàn khác.
Để thực hiện việc này, hãy xác định thực thể tham chiếu bằng ImagenSubjectReference, sau đó truyền thực thể đó đến editImage cùng với câu lệnh. Ngoài ra, hãy đưa vào ImagenEditingConfig chỉ định số lượng editSteps; giá trị editSteps càng cao thì kết quả thường có chất lượng càng tốt:
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 }
Tuỳ chỉnh dựa trên chế độ kiểm soát
Kỹ thuật này tạo hình ảnh mới dựa trên hình ảnh tham khảo chế độ kiểm soát, chẳng hạn như bản phác thảo vẽ tay ("scribble"), hình ảnh cạnh Canny, hoặc lưới khuôn mặt. Mô hình sử dụng hình ảnh chế độ kiểm soát làm hướng dẫn cấu trúc cho bố cục và bố cục của hình ảnh mới, trong khi câu lệnh dạng văn bản cung cấp thông tin chi tiết như màu sắc và kết cấu.
Xác định tham chiếu chế độ kiểm soát bằng ImagenControlReference và cung cấp tham chiếu đó cho editImage cùng với câu lệnh và ImagenEditingConfig với số lượng editSteps (giá trị càng cao thì chất lượng càng có thể cải thiện):
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 }
Tuỳ chỉnh dựa trên kiểu
Bạn có thể tạo hoặc chỉnh sửa hình ảnh để khớp với một kiểu cụ thể từ hình ảnh tham khảo, chẳng hạn như mẫu, kết cấu hoặc thiết kế của hình ảnh đó. Mô hình sử dụng hình ảnh tham khảo để hiểu tính thẩm mỹ cần thiết và áp dụng tính thẩm mỹ đó cho hình ảnh mới được mô tả trong câu lệnh dạng văn bản. Ví dụ: bạn có thể tạo hình ảnh một chú mèo theo kiểu của một bức tranh nổi tiếng bằng cách cung cấp hình ảnh bức tranh đó.
Xác định tham chiếu kiểu bằng ImagenStyleReference và cung cấp tham chiếu đó cho editImage cùng với câu lệnh và ImagenEditingConfig với số lượng editSteps (giá trị càng cao thì chất lượng càng có thể cải thiện):
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 }
Các bước tiếp theo
- Tìm hiểu thêm về Firebase AI Logic trong tài liệu về Firebase.
- Khám phá Danh mục mẫu AI cho Android.