https://kotlinlang.org logo
#compose
Title
# compose
o

Olivier Patry

11/07/2023, 1:14 AM
I have a
Bitmap
in memory which I use to retrieve some information like pixel color at given position. I'd like to partially display this bitmap zoomed around a position. This preview is made using a
Card
sized to my preview size (say
128.dp
). When I try displaying my bitmap (using Coil), the bitmap is necessarily down scaled to card size despite trying to control that. To achieve my zoom, I rely on
Modifier.graphicsLayer()
to apply a scale & translation but this doesn't fully work either, and I guess there is a link with previous issue. Notice that the scaling is pretty straight forward but the result is ugly due to initially downscaled bitmap upscaled afterwards. How would you achieve that? (code in 🧵)
Copy code
Card(
    Modifier
        .offset(x = position.x - (size / 2), y = position.y - (size / 2))
        .size(size),
    shape = CircleShape,
    backgroundColor = color.takeIf { color.alpha > 0f } ?: MaterialTheme.colors.surface,
    border = BorderStroke(2.dp, LocalContentColor.current.copy(alpha = .1f)),
    elevation = 16.dp // FIXME doesn't work :(
) {
    val scale = 10f
    val tX = position.x.value * density
    val tY = position.y.value * density
    AsyncImage(
        screenBitmap,
        contentDescription = null,
        modifier = Modifier
            .graphicsLayer(
                scaleX = scale,
                scaleY = scale,
                translationX = tX,
                translationY = tY
            ),
        contentScale = ContentScale.Crop,
// alignment = Alignment.TopStart,
    )
}
Where position is a
DpOffset
computed with drag gesture detection.
FTR, using
Image(screenBitmap.asImageBitmap(), null)
directly leads to the same issue regarding size being downscaled to parent composable bounds. Using
contentScale = ContentScale.Crop
or not.
a

Albert Chang

11/07/2023, 1:47 AM
You can disable scaling with this:
Copy code
AsyncImage(
    model = ImageRequest.Builder(LocalContext.current)
        .data(screenBitmap)
        .size(Size.ORIGINAL)
        .build()
)
o

Olivier Patry

11/07/2023, 1:51 AM
I tried it already without luck, the image is still downscaled to the parent
Card
size.
I also tried forcing the size using the bitmap dimensions as follow
Copy code
ImageRequest.Builder(LocalContext.current)
    .data(screenBitmap)
    .size(Size(screenBitmap.width, screenBitmap.height))
    //.size(Size.ORIGINAL)
  .build(),
Not working either.
a

Albert Chang

11/07/2023, 1:59 AM
The image is not downscaled. It's just displayed at the size of the card. If you want it to be displayed at original size, you have to also use
contentScale = ContentScale.None
.
🎉 1
o

Olivier Patry

11/07/2023, 2:01 AM
I was using
Crop
thinking that it would take the original size and crop what is outside the bounds of the parent view… Indeed
ContentScale.None
does the job 👍 A bit counter intuitive in my current understanding.
I noticed there was also the
Modifier.magnifier()
that might help to achieve the "zoom" effect (with less control on UI feedback through)