Imagen เป็นโมเดลการสร้างรูปภาพ โดยสามารถใช้เพื่อสร้าง อวตารที่กำหนดเองสำหรับโปรไฟล์ผู้ใช้ หรือเพื่อผสานรวมชิ้นงานภาพที่ปรับเปลี่ยนในแบบของคุณเข้ากับ โฟลว์หน้าจอที่มีอยู่เพื่อเพิ่มการมีส่วนร่วมของผู้ใช้
คุณเข้าถึงโมเดล Imagen จากแอป Android ได้โดยใช้ Firebase AI Logic SDK โมเดล Imagen พร้อมใช้งานโดยใช้ทั้ง ผู้ให้บริการ API ของ Firebase AI Logic: Gemini Developer API (แนะนำสำหรับนักพัฒนาซอฟต์แวร์ส่วนใหญ่ ) และ Vertex AI
ทดลองใช้พรอมต์
การสร้างพรอมต์ที่เหมาะสมมักต้องลองหลายครั้ง คุณสามารถทดลองใช้พรอมต์รูปภาพใน Google AI Studio ซึ่งเป็น IDE สำหรับการออกแบบและการสร้างต้นแบบพรอมต์ ดูเคล็ดลับเกี่ยวกับวิธีปรับปรุงพรอมต์ได้ที่คู่มือแอตทริบิวต์พรอมต์และรูปภาพ
ตั้งค่าโปรเจ็กต์ Firebase และเชื่อมต่อแอป
ทําตามขั้นตอนในเอกสารประกอบของ Firebase เพื่อเพิ่ม Firebase ลงในโปรเจ็กต์ Android
เพิ่มการอ้างอิง Gradle
เพิ่มทรัพยากร Dependency ต่อไปนี้ลงในไฟล์ build.gradle
dependencies {
// Import the BoM for the Firebase platform
implementation(platform("com.google.firebase:firebase-bom:34.5.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
SDK ตรรกะ AI ของ Firebase มีความสามารถในการแต่งภาพขั้นสูงผ่านโมเดล Imagen ซึ่งช่วยให้คุณทำสิ่งต่อไปนี้ได้
- แก้ไขรูปภาพตามมาสก์ ซึ่งรวมถึงการดำเนินการต่างๆ เช่น การแทรก หรือนำวัตถุออก การขยายเนื้อหารูปภาพให้เกินขอบเขตเดิม และการเปลี่ยนพื้นหลัง
- ปรับแต่งรูปภาพโดยใช้สไตล์ที่เฉพาะเจาะจง (ลวดลาย พื้นผิว หรือสไตล์ของศิลปิน) โดยมุ่งเน้นที่วัตถุต่างๆ (เช่น ผลิตภัณฑ์ ผู้คน หรือสัตว์) หรือโดยใช้การควบคุมที่แตกต่างกัน (เช่น ภาพร่างที่วาดด้วยมือ รูปภาพขอบที่คมชัด หรือตาข่ายใบหน้า)
การเริ่มต้นโมเดล
หากต้องการใช้ฟีเจอร์การแก้ไข Imagen ให้ระบุโมเดล Imagen ที่รองรับการแก้ไขรูปภาพ เช่น imgen-3.0-capability-001 เวอร์ชันของโมเดล
val imagenModel = Firebase.ai(backend = GenerativeBackend.vertexAI()) .imagenModel("imagen-3.0-capability-001")
การแก้ไขโดยใช้มาสก์
การแก้ไขตามมาสก์ของ Imagen ช่วยให้แก้ไขรูปภาพได้โดยการกำหนด พื้นที่ที่เฉพาะเจาะจงเพื่อให้โมเดลจัดการ ความสามารถนี้ช่วยให้ทำสิ่งต่างๆ ได้มากมาย รวมถึงการสร้างและใช้มาสก์ การแทรกหรือนำวัตถุออก และการขยายเนื้อหาของรูปภาพให้เกินขอบเขตเดิม
สร้างมาสก์
หากต้องการทำการแก้ไขโดยอิงตามมาสก์ เช่น การแทรกหรือนำออบเจ็กต์ออก คุณจะต้อง กำหนดพื้นที่ที่โมเดลต้องแก้ไข ซึ่งก็คือมาสก์
หากต้องการสร้างมาสก์ คุณสามารถให้โมเดลสร้างมาสก์โดยอัตโนมัติได้โดยใช้
ImagenBackgroundMask() หรือ ImagenSemanticMask() โดยส่ง class
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") } } }
จากนั้นคุณจะสร้างบิตแมปมาสก์ได้โดยวาดเส้นทางบน 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 คุณจะต้องระบุรูปภาพต้นฉบับและมาสก์ที่ไฮไลต์ออบเจ็กต์ที่ต้องการนำออก คุณอาจใส่พรอมต์ข้อความเพื่ออธิบายออบเจ็กต์ ซึ่งจะช่วยให้โมเดลระบุได้อย่างถูกต้อง นอกจากนี้ คุณต้องกำหนด 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ที่จำเป็นของรูปภาพที่ขยาย
คุณอาจใส่พรอมต์อธิบายสำหรับการขยายและระบุ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 }
ขั้นตอนถัดไป
- ดูข้อมูลเพิ่มเติมเกี่ยวกับตรรกะ AI ของ Firebase ในเอกสารประกอบของ Firebase
- สำรวจแคตตาล็อกตัวอย่าง AI ของ Android