Wybieranie kolorów za pomocą interfejsu Palette API

Dobra oprawa wizualna jest niezbędna do osiągnięcia sukcesu przez aplikację, a schematy kolorów są jej podstawowym elementem. Biblioteka Palette to biblioteka Jetpack, która wyodrębnia z obrazów dominujące kolory, aby tworzyć atrakcyjne wizualnie aplikacje.

Biblioteki Palette możesz używać do projektowania motywów układu i stosowania niestandardowych kolorów do elementów wizualnych w aplikacji. Możesz na przykład użyć palety, aby utworzyć kartę tytułową utworu w skoordynowanych kolorach na podstawie okładki albumu lub dostosować kolor paska narzędzi aplikacji, gdy zmienia się obraz tła. Obiekt Palette umożliwia dostęp do kolorów na Bitmap obrazie i udostępnia 6 głównych profili kolorów z mapy bitowej, które pomogą Ci w podejmowaniu decyzji projektowych.

Konfigurowanie biblioteki

Aby użyć biblioteki Palette, dodaj do pliku build.gradle te elementy:

Kotlin

android {
    compileSdkVersion(33)
    ...
}

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

Groovy

android {
    compileSdkVersion 33
    ...
}

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

Tworzenie palety

Obiekt Palette umożliwia dostęp do podstawowych kolorów obrazu, a także do odpowiednich kolorów tekstu nakładanego. Używaj palet, aby projektować styl aplikacji i dynamicznie zmieniać jej schemat kolorów na podstawie danego obrazu źródłowego.

Aby utworzyć paletę, najpierw utwórz instancję Palette.BuilderBitmap. Następnie możesz użyć ikony Palette.Builder, aby dostosować paletę przed jej wygenerowaniem. W tej sekcji opisano generowanie i dostosowywanie palety na podstawie obrazu bitmapowego.

Generowanie instancji palety

Wygeneruj instancję Palette, używając metody from(Bitmap bitmap), aby najpierw utworzyć Palette.Builder z Bitmap.

Generator może tworzyć paletę synchronicznie lub asynchronicznie. Użyj synchronicznego generowania palety, jeśli chcesz utworzyć paletę w tym samym wątku co wywoływana metoda. Jeśli generujesz paletę asynchronicznie, w innym wątku, użyj metody onGenerated(), aby uzyskać do niej dostęp natychmiast po jej utworzeniu.

Poniższy fragment kodu zawiera przykładowe metody generowania palety obu typów:

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.
    }
  });
}

Jeśli musisz ciągle generować palety dla posortowanej listy obrazów lub obiektów, rozważ buforowanie instancji Palette, aby zapobiec spowolnieniu interfejsu. Nie twórz palet w głównym wątku.

Dostosowywanie palety

Palette.Builder umożliwia dostosowanie palety przez wybranie liczby kolorów w wynikowej palecie, obszaru obrazu, którego narzędzie do tworzenia używa do wygenerowania palety, oraz kolorów, które mają być w niej uwzględnione. Możesz na przykład odfiltrować kolor czarny lub sprawić, że narzędzie do tworzenia palety będzie używać tylko górnej połowy obrazu.

Dostosuj rozmiar i kolory palety za pomocą tych metod z klasy Palette.Builder:

addFilter()
Ta metoda dodaje filtr, który wskazuje, jakie kolory są dozwolone w wynikowej palecie. Przekaż własną klasę Palette.Filter i zmodyfikuj jej metodę isAllowed(), aby określić, które kolory mają być filtrowane z palety.
maximumColorCount()
Ta metoda ustawia maksymalną liczbę kolorów w palecie. Wartość domyślna to 16, a optymalna wartość zależy od obrazu źródłowego. W przypadku zdjęć krajobrazów optymalne wartości mieszczą się w zakresie 8–16, a w przypadku zdjęć z twarzami – 24–32. Generowanie palet z większą liczbą kolorów zajmuje Palette.Builder więcej czasu.
setRegion()
Ta metoda określa, którego obszaru mapy bitowej używa narzędzie do tworzenia palety. Tej metody można używać tylko podczas generowania palety z mapy bitowej. Nie ma ona wpływu na oryginalny obraz.
addTarget()
Ta metoda umożliwia samodzielne dopasowanie kolorów przez dodanie do narzędzia Target profilu kolorów. Jeśli domyślny Target jest niewystarczający, zaawansowani programiści mogą utworzyć własny Target za pomocą Target.Builder.

Wyodrębnianie profili kolorów

Zgodnie ze standardami Material Design biblioteka Palette wyodrębnia z obrazu najczęściej używane profile kolorów. Każdy profil jest zdefiniowany przez Target, a kolory wyodrębnione z obrazu bitmapowego są oceniane w odniesieniu do każdego profilu na podstawie nasycenia, luminancji i populacji (liczby pikseli na obrazie bitmapowym reprezentowanych przez kolor). W przypadku każdego profilu kolor z najlepszym wynikiem określa profil kolorów dla danego obrazu.

Domyślnie obiekt Palette zawiera 16 kolorów podstawowych z danego obrazu. Podczas generowania palety możesz dostosować liczbę kolorów za pomocą ikony Palette.Builder. Wyodrębnianie większej liczby kolorów zapewnia więcej potencjalnych dopasowań do każdego profilu kolorów, ale wydłuża też czas generowania palety przez Palette.Builder.

Biblioteka Palette próbuje wyodrębnić te 6 profili kolorów:

  • Jasne, żywe
  • Barwny
  • Ciemne, żywe
  • Jasny wyciszony
  • Wyciszone
  • Ciemny wyciszony

Każda z metod get<Profile>Color()Palette zwraca kolor z palety powiązany z danym profilem, gdzie <Profile> jest zastępowane nazwą jednego z 6 profili kolorów. Na przykład sposób uzyskania profilu kolorów Ciemny żywy to getDarkVibrantColor(). Nie wszystkie obrazy zawierają wszystkie profile kolorów, więc podaj domyślny kolor do zwrócenia.

Ilustracja 1 przedstawia zdjęcie i odpowiadające mu profile kolorów uzyskane za pomocą metod get<Profile>Color().

Obraz przedstawiający zachód słońca po lewej stronie i wyodrębnioną paletę kolorów po prawej stronie.
Rysunek 1. Przykładowy obraz i wyodrębnione z niego profile kolorów przy domyślnej maksymalnej liczbie kolorów (16) w palecie.

Tworzenie schematów kolorów za pomocą próbek

Klasa Palette generuje też Palette.Swatchobiekty dla każdego profilu kolorów. Palette.Swatch zawierają powiązany kolor dla danego profilu, a także jego udział w pikselach.

Próbki kolorów mają dodatkowe metody uzyskiwania więcej informacji o profilu kolorów, takich jak wartości HSL i liczba pikseli. Próbki kolorów mogą pomóc w tworzeniu bardziej kompleksowych schematów kolorów i motywów aplikacji za pomocą metod getBodyTextColor()getTitleTextColor(). Te metody zwracają kolory odpowiednie do użycia na próbce koloru.

Każda z metod get<Profile>Swatch()Palette zwraca próbkę koloru powiązaną z danym profilem, gdzie <Profile> jest zastępowane nazwą jednego z 6 profili kolorów. Chociaż metody palety get<Profile>Swatch() nie wymagają parametrów wartości domyślnej, zwracają null, jeśli dany profil nie istnieje na obrazie. Dlatego przed użyciem próbki sprawdź, czy nie ma wartości null. Na przykład poniższy kod pobiera kolor tekstu tytułu z palety, jeśli próbka Vibrant nie ma wartości null:

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();
    // ...
}

Aby uzyskać dostęp do wszystkich kolorów w palecie, metoda getSwatches() zwraca listę wszystkich próbek wygenerowanych na podstawie obrazu, w tym standardowych 6 profili kolorów.

Poniższy fragment kodu wykorzystuje metody z poprzednich fragmentów kodu do synchronicznego generowania palety, pobierania jej żywego próbnika i zmieniania kolorów paska narzędzi w celu dopasowania ich do obrazu bitmapowego. Ilustracja 2 przedstawia wynikowy obraz i pasek narzędzi.

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);
}
Obraz przedstawiający zachód słońca i pasek narzędzi z elementem TitleTextColor
Rysunek 2. Przykładowy obraz z paskiem narzędzi w żywych kolorach i odpowiednim kolorem tekstu tytułu.