androidioscompose-multiplatform

How to use drawabless in compose multiplatform?


I'm developing a Compose Multiplatform app and want to use the same PNG drawable assets for both Android and iOS.

So far I understand, I need to use the same pngs for both platforms like this:

for android in androidMain:

androidApp/src/main/res/
    drawable-mdpi/icon.png  
    drawable-hdpi/icon.png     
    drawable-xhdpi/icon.png    
    drawable-xxhdpi/icon.png    
    drawable-xxxhdpi/icon.png

for iOS in commonMain

commonMain/composeResources/drawable/
    icon.png
    icon@2x.png
    icon@3x.png

as next step, I need to get that icon in commonMain/kotlin/package/App.kt like

rememberPngPainter("icon.png")

and here begins my problem. First of all, is my approach correct? According to ChaGPT and Gemini, it's the correct, but it doesn't work for iOS part. According to AIs, I should do for Android part like this, which works:

@Composable
actual fun rememberPngPainter(name:String) : Painter {
    @SDrawableRes
    val icon = when(name) {
        "icon" -> R.drawable.icon
        else -> R.drawable.other_icon
    }
    return painterResource(id = icon)
}

for iOS part like this:

import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.graphics.painter.BitmapPainter
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.graphics.asImageBitmap
import platform.UIKit.UIImage

@Composable
actual fun rememberPngPainter(name: String): Painter {
    val icon = when(name) {
        "icon" -> "icon.png"
        else -> "other_icon.png"
    }
    
    val uiImage = UIImage.imageNamed(name)
        ?: error("Image not found: $imageName")
    
    val imageBitmap: ImageBitmap = uiImage.toImageBitmap()
    return BitmapPainter(imageBitmap)
}

which does not work since there is no library out there to use

.toImageBitmap()

and ChatGPT answers me "I can't help you with this". But Gemini gives me alternative to use

painterResource(resource = "icon.png")

which doesn't also exist, whereas Gemini (also aksed ChaGPT about) says that that's here to find:

compose-components-resources = { module = "org.jetbrains.compose.components:components-resources", version.ref = "1.5.1 or higher" }

I checked all versions and there has ever been any painterResource with String input, only

fun painterResource(resource: DrawableResource)

So, I am stuck and don't know what else I could do.

Can anyone help me with this?


Solution

  • Everything is much simpler, create a directory composeResources in composeApp/src/commonMain, create a directory drawable in it. Put your icon.png there.

    Be sure to build the project so that the files are generated.

    And use in the common code:

    Image(
        ...
        painter = painterResource(Res.drawable.icon),
        ...
    )
    

    The documentation describes everything in great detail.