app.gif

AndroidX Palette – библиотека, которая анализирует изображение и достает из него заметные цвета. Эти цвета можно использовать для динамического оформления экрана: фона, топбара, текста, карточек или акцентных элементов. В примере проекта https://github.com/michaelbel/PaletteColors Palette используется на экране деталей: изображение загружается через Coil, из него строится палитра, а фон и цвет текста подстраиваются под картинку.

Подключить зависимости

implementation("androidx.palette:palette")
implementation("io.coil-kt.coil3:coil-compose")
implementation("io.coil-kt.coil3:coil-network-okhttp")

Palette сама не загружает изображения из сети. Она анализирует уже готовый Bitmap. Поэтому рядом с ней нужен загрузчик изображений Coil.

Построить Palette

Palette строится из Bitmap:

val palette = Palette.from(bitmap).generate()

Bitmap получается через Coil:

val request = ImageRequest.Builder(context)
    .data(imageUrl)
    .build()

val result = context.imageLoader.execute(request)
if (result is SuccessResult) {
    Palette.from(result.image.toBitmap()).generate()
}

Не блокировать UI

Анализ изображения может быть тяжелым, особенно если картинка большая или загружается из сети. Работа должна быть вынесена в Dispatchers.IO. LaunchedEffect перезапускает анализ только когда меняется URL изображения. Это важно для Compose: не нужно заново строить Palette на каждую рекомпозицию.

LaunchedEffect(imageUrl) {
    val palette = withContext(Dispatchers.IO) {
        val request = ImageRequest.Builder(context)
            .data(imageUrl)
            .allowHardware(false)
            .build()

        val result = context.imageLoader.execute(request)
        if (result is SuccessResult) {
            Palette.from(result.image.toBitmap()).generate()
        } else {
            null
        }
    }
}

Swatch

Palette возвращает не просто один цвет, а набор swatch-объектов. Swatch содержит основной цвет и рекомендованные цвета текста поверх него. Выбираем сначала насыщенный цвет, а если его нет – доминирующий: