Selecciona colores con la API de Palette

Un buen diseño visual es esencial para el éxito de una app, y los esquemas de color son uno de los principales componentes del diseño. La biblioteca de Palette es una biblioteca de Jetpack que extrae colores destacados de las imágenes para crear apps visualmente atractivas.

Puedes usar la biblioteca de Palette para diseñar temas de diseño y aplicar colores personalizados a los elementos visuales de tu app. Por ejemplo, puedes usar una paleta para crear una tarjeta de título con coordinación de colores para una canción en función de la portada del álbum o para ajustar el color de la barra de herramientas de una app cuando cambia la imagen de fondo. El Palette te da acceso a los colores de una Imagen de Bitmap a la vez que proporcionas seis perfiles de color principales del mapa de bits para informar a las decisiones de diseño.

Cómo configurar la biblioteca

Para usar la biblioteca Palette, agrega lo siguiente a tu build.gradle

Kotlin

android {
    compileSdkVersion(33)
    ...
}

dependencies {
    ...
    implementation("androidx.palette:palette:1.0.0")
}

Groovy

android {
    compileSdkVersion 33
    ...
}

dependencies {
    ...
    implementation 'androidx.palette:palette:1.0.0'
}

Crea una paleta

Un objeto Palette te da acceso a los colores primarios de una así como los colores correspondientes para el texto superpuesto. Usa las paletas para diseñar el estilo de tu app y cambiar dinámicamente su esquema de colores según en una imagen de origen determinada.

Para crear una paleta, primero crea una instancia de un Palette.Builder desde un Bitmap. Luego, puedes usar Palette.Builder para personalizar la paleta antes de generarla. En esta sección, se describe la paleta la generación y personalización a partir de una imagen de mapa de bits.

Genera una instancia de paleta

Genera una instancia de Palette con su from(Bitmap bitmap) para crear primero un Palette.Builder a partir de un Bitmap

El compilador puede generar la paleta de forma síncrona o asíncrona. Usa la generación síncrona de paleta si deseas crear la paleta en el mismo subproceso que el método que se está llamando. Si generas la paleta de forma asíncrona, en otro subproceso, usa el onGenerated() para acceder a la paleta inmediatamente después de crearla.

En el siguiente fragmento de código, se proporcionan métodos de ejemplo para ambos tipos de generación de paletas:

Kotlin

// Generate palette synchronously and return it.
fun createPaletteSync(bitmap: Bitmap): Palette = Palette.from(bitmap).generate()

// Generate palette asynchronously and use it on a different thread using onGenerated().
fun createPaletteAsync(bitmap: Bitmap) {
    Palette.from(bitmap).generate { palette ->
        // Use generated instance.
    }
}

Java

// Generate palette synchronously and return it.
public Palette createPaletteSync(Bitmap bitmap) {
  Palette p = Palette.from(bitmap).generate();
  return p;
}

// Generate palette asynchronously and use it on a different thread using onGenerated().
public void createPaletteAsync(Bitmap bitmap) {
  Palette.from(bitmap).generate(new PaletteAsyncListener() {
    public void onGenerated(Palette p) {
      // Use generated instance.
    }
  });
}

Si necesitas generar paletas continuamente para una lista ordenada de imágenes o los objetos, considera almacenar en caché Palette para evitar un rendimiento lento de la IU. No crees las paletas en el subproceso principal.

Personaliza tu paleta

El Palette.Builder te permite personalizar la paleta. Para ello, puedes elegir la cantidad de colores, el área de la imagen que utiliza el creador para generarla y qué colores se incluyen en ella. Por ejemplo, puedes filtrar el color negro o asegurarte de que el generador solo utiliza la mitad superior de una imagen para generar tu paleta.

Ajusta el tamaño y los colores de la paleta con los siguientes métodos del Clase Palette.Builder:

addFilter()
Este método agrega un filtro que indica los colores que están permitidos en la paleta resultante. Ingresa el tuyo Palette.Filter y modificar su método isAllowed() para determinar qué colores filtrado de la paleta.
maximumColorCount()
Este método establece la cantidad máxima de colores en la paleta. El valor predeterminado es 16, y el valor óptimo depende de la imagen de origen. Para los paisajes, los valores óptimos varían de 8 a 16, mientras que las imágenes con rostros suelen tener valores de 24 a 32. El Palette.Builder tarda más en generar paletas con más colores.
setRegion()
Este método indica qué área del mapa de bits utiliza el creador cuando genera la paleta. Solo puedes usar este método cuando generas la paleta a partir de un mapa de bits, y no afecta la imagen original.
addTarget()
Este método te permite realizar tu propia coincidencia de colores agregando una Target de color al generador. Si el valor predeterminado de Target es insuficientes, los desarrolladores avanzados pueden crear sus propios Target con un Target.Builder

Cómo extraer perfiles de color

Según el estándares de Material en Google Cloud, la biblioteca Palette extrae los perfiles de color de uso común de un imagen. Cada perfil se define con un Target, y los colores extraídos de la imagen de mapa de bits se califican comparando cada perfil en función de la saturación, la luminancia y la resolución (cantidad de píxeles en el mapa de bits representada por el color). Para cada perfil, el color con la mejor calificación define ese perfil de color para la imagen.

De forma predeterminada, un objeto Palette contiene 16 colores primarios de un determinada imagen. Cuando generas la paleta, puedes personalizar la cantidad de colores con Palette.Builder. Extraer más colores proporciona un mayor potencial coincide para cada perfil de color, pero también hace que Palette.Builder tome más tiempo al generar la paleta.

La biblioteca de Palette intenta extraer los siguientes seis perfiles de color:

  • Vibrante claro
  • Vibrante
  • Vibrante oscuro
  • Tenue claro
  • Tenue
  • Tenue oscuro

Cada uno de los métodos get<Profile>Color() en Palette muestra el color en la paleta asociada con ese perfil específico, en la que <Profile> se reemplaza por el nombre de uno de los seis perfiles de color. Por ejemplo, el método para obtener la El perfil de color oscuro vibrante es getDarkVibrantColor() Como no todas las imágenes contienen todos los perfiles de color, proporciona un color predeterminado para mostrar.

En la figura 1, se muestra una foto y los perfiles de color correspondientes de la get<Profile>Color().

Una imagen que muestra un atardecer a la izquierda y la paleta de colores extraída a la derecha.
Figura 1: Una imagen de ejemplo y los perfiles de color extraídos según la cantidad máxima de colores predeterminada (16) para la paleta.

Usa muestras para crear esquemas de colores

La clase Palette también genera objetos Palette.Swatch para cada perfil de color. Los objetos Palette.Swatch contienen lo siguiente: el color asociado a ese perfil, así como la población del color en píxeles.

Las muestras tienen métodos adicionales para acceder a más información sobre el perfil de color, como los valores HSL y la resolución en píxeles. Puedes usar muestras para crear esquemas de colores más completos y temas de apps con los métodos getBodyTextColor() y getTitleTextColor(). Estos métodos muestran colores apropiados para usar sobre el color de la muestra.

Cada método get<Profile>Swatch() de Palette muestra la muestra asociada con ese perfil en particular, en la que <Profile> se reemplaza por el nombre de uno de los seis perfiles de color. Aunque los Los métodos get<Profile>Swatch() no requieren el valor predeterminado value, muestran null si ese perfil en particular que no existe en la imagen. Por lo tanto, comprueba que una muestra no sea nula antes y la usan. Por ejemplo, el siguiente código obtiene el color del texto del título de una paleta si la muestra vibrante no es nula:

Kotlin

val vibrant = myPalette.vibrantSwatch
// In Kotlin, check for null before accessing properties on the vibrant swatch.
val titleColor = vibrant?.titleTextColor

Java

Palette.Swatch vibrant = myPalette.getVibrantSwatch();
if(vibrant != null){
    int titleColor = vibrant.getTitleTextColor();
    // ...
}

Para acceder a todos los colores de una paleta, el método getSwatches() muestra una lista de todas las muestras generadas a partir de una imagen, incluidos los seis perfiles de color estándar.

En el siguiente fragmento de código, se usan los métodos del código anterior para generar una paleta de forma síncrona, obtener su muestra vibrante y cambiar los colores de la barra de herramientas para que coincidan con la imagen del mapa de bits. En la Figura 2, se muestra imagen y barra de herramientas resultantes.

Kotlin

// Set the background and text colors of a toolbar given a bitmap image to
// match.
fun setToolbarColor(bitmap: Bitmap) {
    // Generate the palette and get the vibrant swatch.
    val vibrantSwatch = createPaletteSync(bitmap).vibrantSwatch

    // Set the toolbar background and text colors.
    // Fall back to default colors if the vibrant swatch isn't available.
    with(findViewById<Toolbar>(R.id.toolbar)) {
        setBackgroundColor(vibrantSwatch?.rgb ?:
                ContextCompat.getColor(context, R.color.default_title_background))
        setTitleTextColor(vibrantSwatch?.titleTextColor ?:
                ContextCompat.getColor(context, R.color.default_title_color))
    }
}

Java

// Set the background and text colors of a toolbar given a bitmap image to
// match.
public void setToolbarColor(Bitmap bitmap) {
    // Generate the palette and get the vibrant swatch.
    // See the createPaletteSync() method from the preceding code snippet.
    Palette p = createPaletteSync(bitmap);
    Palette.Swatch vibrantSwatch = p.getVibrantSwatch();

    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);

    // Load default colors.
    int backgroundColor = ContextCompat.getColor(getContext(),
        R.color.default_title_background);
    int textColor = ContextCompat.getColor(getContext(),
        R.color.default_title_color);

    // Check that the Vibrant swatch is available.
    if(vibrantSwatch != null){
        backgroundColor = vibrantSwatch.getRgb();
        textColor = vibrantSwatch.getTitleTextColor();
    }

    // Set the toolbar background and text colors.
    toolbar.setBackgroundColor(backgroundColor);
        toolbar.setTitleTextColor(textColor);
}
Una imagen que muestra un atardecer y una barra de herramientas con TitleTextColor dentro
Figura 2: Una imagen de ejemplo con la barra de herramientas de colores brillantes y el color del texto del título correspondiente.