programacion - Diferencias entre los colores de la paleta de Android
libros de android studio pdf gratis (1)
Editar
Para tener una mejor idea de la clase de la paleta de Android, decidí crear una aplicación sencilla para probar algunas de sus características. Si está interesado, puede encontrar la aplicación en Play Store: https://play.google.com/store/apps/details?id=com.tonyw.sampleapps.palettecolorextraction . Básicamente, solo tiene imágenes y los colores que extrae la clase Paleta (que se mencionan a continuación), y también puede agregar sus propias imágenes para probarlas. Puede encontrar mi código fuente en Github: https://github.com/tony-w/PaletteColorExtraction
Capturas de pantalla
Post original
¿Puede alguien describir las diferencias entre los colores que se pueden extraer de un mapa de bits con la clase de paleta de Android ?
- Vibrante
- Oscuridad vibrante
- Luz vibrante
- Apagado
- Silencio Oscuro
- Luz apagada
¿Es solo que los colores apagados son más apagados que los colores vibrantes? ¿Se supone que la oscuridad y la luz se ajustan mejor a los temas de diseño de material claro y oscuro de Lollipop, respectivamente?
Esa es una muy buena pregunta. Si observa el código fuente , puede ver que las diferentes muestras se eligen al analizar el perfil de color HSL de los píxeles en la imagen, en función de los rangos objetivo de luminancia, saturación y población (cuántos píxeles en la imagen se representan la muestra). Utiliza un cálculo de promedio ponderado con preferencia a la luminancia , luego a la saturación y luego a la población .
En general, los colores vibrantes son más saturados que los colores apagados, los colores oscuros son más oscuros y las muestras claras son más claras. El que use dependerá del efecto general que desee.
Chris Banes escribió en su blog "Vibrant y Dark Vibrant son los que más usarán los desarrolladores", pero en la práctica no es tan simple como eso.
Un ejemplo que he encontrado es el método applyPalette
en la aplicación de ejemplo de Romain Guy de Google IO 2014, aunque el código supone que se encontrarán las distintas muestras (posiblemente porque está trabajando con imágenes conocidas).
Dependiendo de la imagen, es posible que no se encuentren algunos tipos de muestras, así que asegúrese de tener en cuenta esa posibilidad en su código.
Por ejemplo, podría intentar obtener muestras de la paleta en un orden específico, por ejemplo, para un tema Oscuro, podría intentar obtener Vibrant Dark, luego Muted Dark, y luego retroceder en un color predeterminado.
Si quieres algo que sea un poco más predecible, también es posible obtener el color más representado, como este:
public static Palette.Swatch getDominantSwatch(Palette palette) {
// find most-represented swatch based on population
return Collections.max(palette.getSwatches(), new Comparator<Palette.Swatch>() {
@Override
public int compare(Palette.Swatch sw1, Palette.Swatch sw2) {
return Integer.compare(sw1.getPopulation(), sw2.getPopulation());
}
});
}
Los valores HSL para cada muestra también son accesibles, por lo que puede escribir una rutina similar para elegir, por ejemplo, la muestra más saturada que no es el color dominante.
Usando objetivos personalizados
Otra cosa que he encontrado útil es definir algunos objetivos personalizados además de los 6 objetivos definidos en Palette.Target
, con diferentes valores de peso y luminosidad y saturación del objetivo, para aumentar la posibilidad de encontrar un color útil.
Por ejemplo, puede pedirle al cuantizador de Palette que incluya una muestra del color más dominante que cumpla con los criterios de filtro actuales con un objetivo como este:
public static final Target DOMINANT;
static {
DOMINANT = new Target.Builder().setPopulationWeight(1f)
.setSaturationWeight(0f)
.setLightnessWeight(0f)
.setExclusive(false)
.build();
}
Y puede obtener algunas muestras útiles que le dan mayor prioridad a la ligereza que los objetivos de valores como este:
public static final Target DARK;
public static final Target LIGHT;
public static final Target NEUTRAL;
static {
DARK = new Target.Builder().setMinimumLightness(0f)
.setTargetLightness(0.26f)
.setMaximumLightness(0.5f)
.setMinimumSaturation(0.1f)
.setTargetSaturation(0.6f)
.setMaximumSaturation(1f)
.setPopulationWeight(0.18f)
.setSaturationWeight(0.22f)
.setLightnessWeight(0.60f)
.setExclusive(false)
.build();
LIGHT = new Target.Builder().setMinimumLightness(0.50f)
.setTargetLightness(0.74f)
.setMaximumLightness(1.0f)
.setMinimumSaturation(0.1f)
.setTargetSaturation(0.7f)
.setMaximumSaturation(1f)
.setPopulationWeight(0.18f)
.setSaturationWeight(0.22f)
.setLightnessWeight(0.60f)
.setExclusive(false)
.build();
NEUTRAL = new Target.Builder().setMinimumLightness(0.20f)
.setTargetLightness(0.5f)
.setMaximumLightness(0.8f)
.setMinimumSaturation(0.1f)
.setTargetSaturation(0.6f)
.setMaximumSaturation(1f)
.setPopulationWeight(0.18f)
.setSaturationWeight(0.22f)
.setLightnessWeight(0.60f)
.setExclusive(false)
.build();
}
Puede acceder a la muestra encontrada para un objetivo personalizado después de que se genere utilizando Palette.getSwatchForTarget , por ejemplo:
Palette.Swatch neutral = Palette.getSwatchForTarget(NEUTRAL);
Tenga en cuenta el filtro predeterminado
Por defecto, Palette
tiene un Palette.Filter
que rechaza los colores muy cercanos al blanco o negro, así como los colores "muy cercanos a la línea I roja", que creo se refieren a los colores isócronos que son difíciles para las personas con ceguera al color rojo-ciego .
Mi teoría es que rechaza los colores casi blanco y casi negro para ayudar a evitar que aquellos sean elegidos como colores "saturados" cuando la saturación es altamente ponderada.
Sin embargo, el resultado de este filtro es que no se encontrarán muestras para imágenes que consistan completamente de píxeles casi blancos y / o casi negros, así como una tendencia a evitar la elección de colores con un tono rosado.
Sin embargo, es posible eliminar este filtro utilizando Palette.Builder.clearFilters()
, y agregar su propio filtro con Palette.Builder.addFilter()
.
En mi código, elegí hacer un segundo intento de generar una paleta si el primer intento no devuelve ninguna muestra:
Palette palette = new Palette.Builder(bitmap).addTarget(DOMINANT)
.addTarget(DARK)
.addTarget(LIGHT)
.addTarget(NEUTRAL)
.generate();
if(palette.getSwatches().isEmpty()) {
Log.v(TAG, "Getting alternate (UNFILTERED) palette.");
palette = new Palette.Builder(bitmap).addTarget(DOMINANT)
.addTarget(DARK)
.addTarget(LIGHT)
.addTarget(NEUTRAL)
.clearFilters() /// allow isBlack(), isWhite(), isNearRedILine()
.generate();
}
Encadenar los intentos conserva la utilidad del filtro predeterminado en la mayoría de los casos, pero aún así le permite encontrar muestras de imágenes que el valor predeterminado rechazaría por completo.