ใน Compose ระบบจะใช้ออบเจ็กต์ Painter
เพื่อแสดงสิ่งที่วาดได้ (แทนที่ Drawable
API ที่กําหนดไว้ใน Android) และส่งผลต่อค่าการวัดและเลย์เอาต์ของคอมโพสิเบิลที่เกี่ยวข้องซึ่งใช้ออบเจ็กต์ดังกล่าว A
BitmapPainter
ใช้ ImageBitmap
ที่สามารถวาด Bitmap
บนหน้าจอ
สําหรับกรณีการใช้งานส่วนใหญ่ การใช้ painterResource()
ด้านบนจะแสดง Painter ที่ถูกต้องสําหรับชิ้นงาน (เช่น BitmapPainter
หรือ VectorPainter
) ดูข้อมูลเพิ่มเติมเกี่ยวกับความแตกต่างระหว่าง Painter 2 ประเภทได้ที่ส่วน ImageBitmap กับ ImageVector
Painter
แตกต่างจาก DrawModifier
ซึ่งจะวาดภายในขอบเขตที่ได้รับอย่างเคร่งครัดและไม่มีอิทธิพลต่อการวัดผลหรือเลย์เอาต์ของคอมโพสิเบิล
หากต้องการสร้างโปรแกรมวาดภาพที่กำหนดเอง ให้ขยายคลาส Painter
และใช้เมธอด onDraw
ซึ่งจะอนุญาตให้เข้าถึง DrawScope
เพื่อวาดกราฟิกที่กำหนดเอง นอกจากนี้ คุณยังลบล้าง intrinsicSize
ได้ด้วย ซึ่งจะใช้เพื่อส่งผลต่อ Composable ที่อยู่ในนั้น ดังนี้
class OverlayImagePainter constructor( private val image: ImageBitmap, private val imageOverlay: ImageBitmap, private val srcOffset: IntOffset = IntOffset.Zero, private val srcSize: IntSize = IntSize(image.width, image.height), private val overlaySize: IntSize = IntSize(imageOverlay.width, imageOverlay.height) ) : Painter() { private val size: IntSize = validateSize(srcOffset, srcSize) override fun DrawScope.onDraw() { // draw the first image without any blend mode drawImage( image, srcOffset, srcSize, dstSize = IntSize( this@onDraw.size.width.roundToInt(), this@onDraw.size.height.roundToInt() ) ) // draw the second image with an Overlay blend mode to blend the two together drawImage( imageOverlay, srcOffset, overlaySize, dstSize = IntSize( this@onDraw.size.width.roundToInt(), this@onDraw.size.height.roundToInt() ), blendMode = BlendMode.Overlay ) } /** * Return the dimension of the underlying [ImageBitmap] as it's intrinsic width and height */ override val intrinsicSize: Size get() = size.toSize() private fun validateSize(srcOffset: IntOffset, srcSize: IntSize): IntSize { require( srcOffset.x >= 0 && srcOffset.y >= 0 && srcSize.width >= 0 && srcSize.height >= 0 && srcSize.width <= image.width && srcSize.height <= image.height ) return srcSize } }
เมื่อเรามี Painter
ที่กําหนดเองแล้ว เราจะวางซ้อนรูปภาพใดก็ได้บนรูปภาพต้นทาง ดังนี้
val rainbowImage = ImageBitmap.imageResource(id = R.drawable.rainbow) val dogImage = ImageBitmap.imageResource(id = R.drawable.dog) val customPainter = remember { OverlayImagePainter(dogImage, rainbowImage) } Image( painter = customPainter, contentDescription = stringResource(id = R.string.dog_content_description), contentScale = ContentScale.Crop, modifier = Modifier.wrapContentSize() )
ผลลัพธ์ของการรวมรูปภาพ 2 รูปด้วยโปรแกรมวาดภาพที่กำหนดเองมีดังนี้
นอกจากนี้ คุณยังใช้โปรแกรมวาดภาพที่กำหนดเองร่วมกับ Modifier.paint(customPainter)
เพื่อวาดเนื้อหาไปยังคอมโพสิเบิลได้ ดังนี้
val rainbowImage = ImageBitmap.imageResource(id = R.drawable.rainbow) val dogImage = ImageBitmap.imageResource(id = R.drawable.dog) val customPainter = remember { OverlayImagePainter(dogImage, rainbowImage) } Box( modifier = Modifier.background(color = Color.Gray) .padding(30.dp) .background(color = Color.Yellow) .paint(customPainter) ) { /** intentionally empty **/ }
แนะนำสำหรับคุณ
- หมายเหตุ: ข้อความลิงก์จะแสดงเมื่อ JavaScript ปิดอยู่
- ImageBitmap เทียบกับ ImageVector {:#bitmap-vs-vector}
- กราฟิกในเครื่องมือเขียน
- กำลังโหลดรูปภาพ {:#loading-images}