Imagen เป็นโมเดลการสร้างรูปภาพ ซึ่งใช้สร้างอวาตาร์ที่กำหนดเองสำหรับโปรไฟล์ผู้ใช้ หรือผสานรวมชิ้นงานภาพที่ปรับเปลี่ยนในแบบของคุณลงในโฟลว์หน้าจอที่มีอยู่เพื่อเพิ่มการมีส่วนร่วมของผู้ใช้ได้
คุณเข้าถึง โมเดล Imagen จากแอป Android ได้โดยใช้ Firebase AI Logic SDK โมเดล Imagen พร้อมให้บริการโดยใช้ผู้ให้บริการ Firebase AI Logic API ทั้ง 2 ราย ได้แก่ Gemini Developer API (แนะนำสำหรับนักพัฒนาซอฟต์แวร์ส่วนใหญ่) และ Vertex AI
ลองใช้พรอมต์
การสร้างพรอมต์ที่เหมาะสมมักต้องลองหลายครั้ง คุณสามารถลองใช้ พรอมต์รูปภาพใน Google AI Studio ซึ่งเป็น IDE สำหรับการออกแบบพรอมต์ และการสร้างต้นแบบ ดูเคล็ดลับเกี่ยวกับวิธีปรับปรุงพรอมต์ได้ใน คู่มือพรอมต์และแอตทริบิวต์รูปภาพ
ตั้งค่าโปรเจ็กต์ Firebase และเชื่อมต่อแอป
ทำตามขั้นตอนในเอกสารประกอบของ Firebase เพื่อ เพิ่ม Firebase ลงในโปรเจ็กต์ Android
เพิ่มทรัพยากร Dependency ของ Gradle
เพิ่มทรัพยากร Dependency ต่อไปนี้ลงในไฟล์ build.gradle
dependencies {
// Import the BoM for the Firebase platform
implementation(platform("com.google.firebase:firebase-bom:34.12.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() แล้วส่ง รหัส
คลาส
นอกจากนี้ คุณยังวาดมาสก์บนหน้าจอด้วยตนเองได้โดยสร้างบิตแมปมาสก์แล้วแปลงเป็น ImagenRawMask คุณสามารถใช้ detectDragGestures และ Canvas เพื่อใช้ UI การวาดมาสก์ด้วย 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") } } }
จากนั้นสร้างบิตแมปมาสก์โดยวาดเส้นทางบน 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 }
ตรวจสอบว่ามาสก์มีขนาดเท่ากับรูปภาพต้นฉบับ ดูรายละเอียดเพิ่มเติมได้ที่ตัวอย่างแคตตาล็อก 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 คุณจะต้องระบุรูปภาพต้นฉบับและa
มาสก์ที่ไฮไลต์วัตถุที่ต้องการ
นำออก นอกจากนี้ คุณยังใส่พรอมต์ข้อความเพื่ออธิบายวัตถุได้ด้วย ซึ่งจะช่วยให้โมเดลระบุวัตถุได้อย่างถูกต้อง นอกจากนี้ คุณต้องตั้งค่า editMode ภายใน ImagenEditingConfig เป็น 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 ที่จำเป็นของรูปภาพที่ขยาย
นอกจากนี้ คุณยังใส่พรอมต์คำอธิบายสำหรับการขยายและระบุ
the 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 เพื่อสร้างหรือแก้ไขรูปภาพตามรูปภาพอ้างอิงที่ระบุวัตถุ การควบคุม หรือสไตล์ คุณทำได้โดยระบุพรอมต์ข้อความพร้อมกับรูปภาพอ้างอิงอย่างน้อย 1 รูปเพื่อเป็นแนวทางให้โมเดล
ปรับแต่งตามวัตถุ
คุณสามารถสร้างรูปภาพใหม่ของวัตถุที่เฉพาะเจาะจงจากรูปภาพอ้างอิง (เช่น ผลิตภัณฑ์ บุคคล หรือสัตว์) เพียงระบุพรอมต์ข้อความและรูปภาพอ้างอิงของวัตถุอย่างน้อย 1 รูป เช่น คุณสามารถอัปโหลดรูปภาพสัตว์เลี้ยงและสร้างรูปภาพใหม่ของสัตว์เลี้ยงในสภาพแวดล้อมที่แตกต่างไปโดยสิ้นเชิง
หากต้องการทำเช่นนี้ ให้กำหนดข้อมูลอ้างอิงของวัตถุโดยใช้ ImagenSubjectReference แล้วส่งไปยัง editImage พร้อมกับพรอมต์ นอกจากนี้ ให้ใส่ ImagenEditingConfig ที่ระบุจำนวน editSteps โดยทั่วไปค่า 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 แล้วส่งไปยัง editImage พร้อมกับพรอมต์และ ImagenEditingConfig ที่มีจำนวน editSteps (ค่าที่สูงขึ้นอาจปรับปรุงคุณภาพได้)
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 แล้วส่งไปยัง editImage พร้อมกับพรอมต์และ ImagenEditingConfig ที่มีจำนวน editSteps (ค่าที่สูงขึ้นอาจปรับปรุงคุณภาพได้)
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
- สำรวจแคตตาล็อกตัวอย่าง AI ของ Android