Imagen là một mô hình tạo hình ảnh. Bạn có thể dùng tính năng 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 của mình bằng SDK Firebase AI Logic. Bạn có thể sử dụng các mô hình Imagen bằng cả nhà cung cấp API Firebase AI Logic: Gemini Developer API (được đề xuất cho hầu hết các nhà phát triển) và Vertex AI.
Thử nghiệm với câu lệnh
Việc tạo ra câu lệnh lý tưởng thường mất nhiều lần thử. Bạn có thể thử nghiệm với câu lệnh tạo hình ảnh trong AI Studio của Google, 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 của bạn
Làm theo các bước trong tài liệu của 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.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")
}
Tạo hình ảnh
Để tạo hình ảnh trong ứng dụng Android, hãy bắt đầu bằng cách khởi tạo một ImagenModel
bằng 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.ai(backend = GenerativeBackend.googleAI()).imagenModel(
"imagen-4.0-generate-001",
config,
ImagenSafetySettings.builder()
.setSafetyFilterLevel(ImagenSafetyFilterLevel.BLOCK_LOW_AND_ABOVE)
.setPersonFilterLevel(ImagenPersonFilterLevel.BLOCK_ALL)
.build())
);
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
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();
}
Chỉnh sửa hình ảnh bằng Imagen
SDK Firebase AI Logic cung cấp các chức năng chỉnh sửa ả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 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ó đường viền rõ ràng 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ư imgen-3.0-capability-001
. phiên bản của mô hình:
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 khu vực cụ thể để mô hình thao tác. Tính năng này cho phép thực hiện nhiều 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 thao tác chỉnh sửa dựa trên mặt nạ (chẳng hạn như chèn hoặc xoá các đối tượng), bạn cần xác định vùng mà mô hình cần chỉnh sửa, đó là mặt nạ.
Để tạo một 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ột 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 một 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 của mình 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 = createMask(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 = 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
}
Đảm bảo mặt nạ có cùng kích thước với hình ảnh nguồn. Hãy xem Mẫu danh mục AI của 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 được gọi là tô màu nội dung bị thiếu. Mô hình sẽ tạo và chèn nội dung mới vào vùng bị che được 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 một đối tượng ImagenEditingConfig
, đảm bảo thuộc tính editMode
của đối tượng đó đượ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(
sources = listOf(
ImagenRawImage(originalImage),
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 chỉnh sửa ảnh giúp bạn loại bỏ 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 sẽ cần cung cấp hình ảnh gốc và một mặt nạ làm nổi bật đối tượng mà bạn muốn xoá. Nếu muốn, bạn có thể thêm một câu lệnh dạng văn bản để mô tả đối tượng. Câu lệnh này có thể hỗ trợ mô hình xác định chính xác đối tượng. 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(
sources = listOf(
ImagenRawImage(originalImage),
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òn gọi là vẽ mở rộng) 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 mở rộng.
Nếu muốn, bạn có thể thêm một câu lệnh mô tả cho phần mở rộng và chỉ định ImagenImagePlacement
của hình ảnh gốc trong hình ảnh mới được tạo:
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
}
Thay thế nền
Bạn có thể thay thế nền của một 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, một đối tượng ImagenBackgroundMask
(chứa câu lệnh dạng văn bản cho nền mới) và một ImagenEditingConfig
có 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(
sources = listOf(
ImagenRawImage(originalImage),
ImagenBackgroundMask(),
),
prompt = prompt,
config = ImagenEditingConfig(ImagenEditMode.INPAINT_INSERTION)
)
return editedImage
}
Tuỳ chỉnh
Bạn có thể sử dụng khả năng tuỳ 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 một chủ thể, chế độ kiểm soát hoặc kiểu. Việc này được thực hiện bằng cách cung cấp một 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 một chủ đề
Bạn có thể tạo hình ảnh mới về một chủ thể cụ thể từ một hình ảnh tham khảo (ví dụ: sản phẩm, người hoặc động vật). Bạn chỉ cần cung cấp một câu lệnh dạng văn bản và ít nhất một hình ảnh tham khảo về chủ đề. Ví dụ: bạn có thể tải ảnh thú cưng của mình lên và tạo một hình ảnh mới cho thú cưng đó trong một môi trường hoàn toàn khác.
Để làm vậy, hãy xác định tham chiếu chủ đề bằng ImagenSubjectReference
rồi truyền tham chiếu đó đến editImage
cùng với câu lệnh của bạn. Ngoài ra, hãy thêm một 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,
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
}
Tuỳ chỉnh dựa trên một chế độ kiểm soát
Kỹ thuật này tạo ra một hình ảnh mới dựa trên hình ảnh tham chiếu kiểm soát, chẳng hạn như bản phác thảo vẽ tay ("vẽ nguệch ngoạc"), hình ảnh cạnh Canny hoặc lưới khuôn mặt. Mô hình này sử dụng hình ảnh kiểm soát làm hướng dẫn về cấu trúc cho bố cục và thành phần của hình ảnh mới, trong khi câu lệnh văn bản cung cấp các thông tin chi tiết như màu sắc và hoạ tiết.
Xác định một tham chiếu kiểm soát bằng ImagenControlReference
và cung cấp tham chiếu đó cho editImage
cùng với một 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, 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
}
Tuỳ chỉnh dựa trên một kiểu
Bạn có thể tạo hoặc chỉnh sửa hình ảnh để có phong cách cụ thể từ mộ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 này sử dụng hình ảnh tham khảo để hiểu được 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 bằng văn bản. Ví dụ: bạn có thể tạo hình ảnh một chú mèo theo phong cách của một bức tranh nổi tiếng bằng cách cung cấp hình ảnh của bức tranh đó.
Xác định một tham chiếu kiểu bằng ImagenStyleReference
và cung cấp tham chiếu đó cho editImage
cùng với một 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,
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
}
Các bước tiếp theo
- Tìm hiểu thêm về Logic AI của Firebase trong tài liệu của Firebase.
- Khám phá Danh mục mẫu AI cho Android.