androidkotlinandroid-jetpack-composeandroid-drawableandroid-bitmap

How to apply ColorFilter to a BitmapDescriptor/Drawable?


I need to add a BitmapDescriptor to my Polyline in Jetpack Compose google maps:

val arrowBitmapDescriptor: BitmapDescriptor by remember { mutableStateOf(BitmapDescriptorFactory.fromResource(R.drawable.arrow)) }
Polyline(
    points = polylinePoints,
    endCap = CustomCap(arrowBitmapDescriptor, 30f),
    color = Color(0xff0e71b8)
)

But I need the bitmapDescriptor to be colorized to the same color as the Polyline, in this case 0xff0e71b8.

How can that be done?

In Android Views it was possible this way, but I can't find how to do this with jetpack compose BitmapDescriptor:

public BitmapDescriptor getEndCapIcon(int color) {
    Drawable drawable = ContextCompat.getDrawable(this, R.drawable.arrow);
    drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
    drawable.setColorFilter(color, PorterDuff.Mode.MULTIPLY);
    android.graphics.Bitmap bitmap = android.graphics.Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(bitmap);
    drawable.draw(canvas);
    return BitmapDescriptorFactory.fromBitmap(bitmap);
}

Solution

  • I don't think there is built-in API to directly tint a drawable for a BitmapDescriptor, so you’ll need to do it manually, like load and tint the drawable, then draw it onto a bitmap.

    Update: Replaced deprecated setColorFilter with colorFilter - a solution provided by @NullPointerException

    fun coloredBitmapDescriptor(
        @DrawableRes drawableRes: Int,
        context: Context,
        color: androidx.compose.ui.graphics.Color
    ): BitmapDescriptor {
        val drawable = ContextCompat.getDrawable(context, drawableRes)!!
        drawable.setBounds(0, 0, drawable.intrinsicWidth, drawable.intrinsicHeight)
        drawable.colorFilter = BlendModeColorFilterCompat.createBlendModeColorFilterCompat(
            color.toArgb(),
            BlendModeCompat.SRC_ATOP
        )
    
        val bitmap = Bitmap.createBitmap(
            drawable.intrinsicWidth,
            drawable.intrinsicHeight,
            Bitmap.Config.ARGB_8888
        )
        val canvas = Canvas(bitmap)
        drawable.draw(canvas)
    
        return BitmapDescriptorFactory.fromBitmap(bitmap)
    }
    
    

    And its usage:

    val arrayBitmapDescriptor: BitmapDescriptor by remember {
            mutableStateOf(
                coloredBitmapDescriptor(R.drawable.ic_location_on, context, Color(0xff0e71b8))
            )
        }