https://kotlinlang.org logo
Title
o

orangy

01/08/2021, 4:25 PM
I’m trying to implement
backgroundImage
modifier like this:
@Composable
fun Modifier.backgroundImage(bitmap: ImageBitmap, contentScale: ContentScale = ContentScale.Crop): Modifier {
    val imagePainter = remember(bitmap) { ImagePainter(bitmap) }
    return paint(imagePainter, false, contentScale = contentScale)
}
But if I do it like this it doesn’t show any content. If I implement my own
DrawImageBackgroundModifier
with trivial draw using drawImage and drawContent, it works as expected. What I’m missing?
j

jim

01/08/2021, 5:03 PM
cc @Nader Jawad
n

Nader Jawad

01/08/2021, 8:12 PM
Looks like the
sizeToIntrinsics
flag is false here which means that the default size of the bitmap will be ignored and it will only draw within the bounds of the composable. To verify, force the composable to have a non-zero size (ex.
Modifier.size(100.dp, 100.dp)
and see if that works. If you want the background to the size of the background image, make sure to pass true for the second argument of the
paint
method
o

orangy

01/09/2021, 9:39 AM
True or false doesn’t make any difference here, I tried. The background is correctly stretched to the size of the composable (fillSize Box in this case). But no content.
n

Nader Jawad

01/11/2021, 6:50 PM
Can you share more of the composable source?
o

orangy

01/16/2021, 10:23 AM
(sorry for late reply, I’m on vacation)
fun main() = Window(
    size = IntSize(950, 650),
    centered = true,
    title = "Example"
) {
    MaterialTheme(colors = LightGameColors) {
        Box(Modifier.backgroundImage(imageResource("ui/background-town.jpg")).fillMaxSize()) {
            Text("SAMPLE", color = Color.White)
        }
    }
}

fun Modifier.backgroundImage(image: ImageBitmap, maintainAspect: Boolean = true): Modifier {
    return then(
        DrawImageBackgroundModifier(image, maintainAspect, debugInspectorInfo {
            name = "backgroundImage"
            properties["image"] = image
        })
    )
}

@Composable
fun Modifier.backgroundImage2(bitmap: ImageBitmap, contentScale: ContentScale = ContentScale.Crop): Modifier {
    val imagePainter = remember(bitmap) { ImagePainter(bitmap) }
    return paint(imagePainter, contentScale = contentScale)
}
With
backgroundImage
it works as expected, while with
backgroundImage2
it doesn’t
Ah, forgot to include this
private class DrawImageBackgroundModifier(
    val image: ImageBitmap,
    val maintainAspect: Boolean,
    inspectorInfo: InspectorInfo.() -> Unit
) :
    DrawModifier,
    InspectorValueInfo(inspectorInfo) {

    override fun ContentDrawScope.draw() {
        val width = size.width.toInt()
        val height = size.height.toInt()
        if (maintainAspect) {
            val imageWidth = image.width
            val imageHeight = image.height
            val imageAspect = imageWidth.toDouble() / imageHeight 
            val areaAspect = width.toDouble() / height 
            val srcWidth = if (imageAspect > areaAspect) (imageHeight * areaAspect).toInt() else imageWidth
            val srcHeight = if (imageAspect < areaAspect) (imageWidth / areaAspect).toInt() else imageHeight

            drawImage(image, srcSize = IntSize(srcWidth, srcHeight), dstSize = IntSize(width, height))
        } else {
            drawImage(image, dstSize = IntSize(width, height))
        }
        drawContent()
    }
}
@Nader Jawad