Compose에서 Painter
객체는 그릴 수 있는 항목을 나타내고(Android에서 정의된 Drawable
API의 대체 API) 객체를 사용하고 있는 컴포저블의 측정 및 레이아웃에 영향을 미치는 데 사용됩니다. BitmapPainter
는 ImageBitmap
을 사용하여 화면에 Bitmap
을 그릴 수 있습니다.
대부분의 사용 사례에서 위의 painterResource()
를 사용하면 애셋에 맞는 올바른 페인터(예: BitmapPainter
또는 VectorPainter
)가 반환됩니다. 둘의 차이점에 관한 자세한 내용은 ImageBitmap과 ImageVector 섹션을 참고하세요.
Painter
는 지정된 경계 내에서 엄격하게 그려지고 컴포저블의 측정 또는 레이아웃에 영향을 주지 않는 DrawModifier
와 다릅니다.
맞춤 페인터를 만들려면 Painter
클래스를 확장하고 onDraw
메서드를 구현합니다. 이렇게 하면 DrawScope
에 액세스하여 맞춤 그래픽을 그릴 수 있습니다. 또한, 맞춤 페인터가 포함된 컴포저블에 영향을 미치는 데 사용되는 intrinsicSize
를 재정의할 수 있습니다.
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() )
두 이미지를 맞춤 페인터와 결합한 출력은 다음과 같습니다.
맞춤 페인터를 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}
- Compose의 그래픽
- 이미지 로드 중 {:#loading-images}