I’m encountering a problem when using the Image component in Jetpack Compose. Here’s the situation:
I need to display an image that is smaller than its container with the ContentScale.Fit effect. To achieve this, I use Modifier.fillMaxSize(), which works as expected. However, I also need to apply clipping to this image.
The issue arises because the clipping happens after fillMaxSize() is applied, leading to the clip being based on the filled size rather than the original image size. This prevents me from achieving a proper clip of the image content.
Here’s a simplified version of the code illustrating the problem:
fun drawToBitmap(): ImageBitmap {
val drawScope = CanvasDrawScope()
val size = Size(300f, 300f) // simple example of 300px by 300px image
val bitmap = ImageBitmap(size.width.toInt(), size.height.toInt())
val canvas = Canvas(bitmap)
drawScope.draw(
density = Density(1f),
layoutDirection = LayoutDirection.Ltr,
canvas = canvas,
size = size,
) {
// Draw whatever you want here; for instance, a white background and a red line.
drawRect(color = Color.White, topLeft = Offset.Zero, size = size)
drawLine(
color = Color.Red,
start = Offset.Zero,
end = Offset(size.width, size.height),
strokeWidth = 100f
)
}
return bitmap
}
@Preview
@Composable
fun ImageTest(modifier: Modifier = Modifier) {
val bitmap = drawToBitmap()
Box(modifier.fillMaxSize().background(Color.Gray), contentAlignment = Alignment.Center) {
Image(
bitmap, null,
Modifier
.fillMaxSize()
.clip(CircleShape)
)
}
}
With this code, the clipping is done on the filled size, not on the image itself. If I remove fillMaxSize(), the image won’t scale to fit the parent layout.
How can I achieve a combination of ContentScale.Fit to scale the image to the size of its container and also properly clip the image based on its original dimensions?
fillMaxSize() + clip(CircleShape) : right size, clip wrong
only fillMaxSize() : right size, no clip
only clip() : wrong size, clip right