Wybieranie kolorów za pomocą interfejsu Palette API

Dobry projekt wizualny jest kluczowy dla sukcesu aplikacji, a schematy kolorów stanowią główny element projektu. Biblioteka palet to biblioteka Jetpacka, która wyodrębnia wyróżniające się kolory z obrazów, aby tworzyć atrakcyjne wizualnie aplikacje.

Biblioteki palety możesz używać do projektowania motywów układu i zastosowywania niestandardowych kolorów do elementów wizualnych w aplikacji. Możesz na przykład użyć palety do utworzenia kolorystycznie dopasowanej karty tytułowej utworu na podstawie okładki albumu lub dostosować kolor paska narzędzi aplikacji, gdy zmieni się obraz tła. Obiekt Palette zapewnia dostęp do kolorów w obrazie Bitmap, a także 6 głównych profili kolorów z pliku bitmapy, które pomogą Ci w podejmowaniu wyborów projektowych.

Konfigurowanie biblioteki

Aby korzystać z biblioteki Palette, dodaj do 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 zapewnia dostęp do kolorów podstawowych na obrazie oraz do odpowiadających im kolorów tekstu nałożonego. Palety możesz używać do projektowania stylu aplikacji i dynamicznego zmieniania jej schematu kolorów na podstawie wybranego obrazu źródłowego.

Aby utworzyć paletę, najpierw utwórz instancję Palette.Builder z Bitmap. Następnie możesz użyć opcji Palette.Builder, aby dostosować paletę przed jej wygenerowaniem. W tej sekcji opisujemy generowanie palety i dostosowywanie ich z poziomu obrazu bitmapy.

Generowanie instancji palety

Wygeneruj instancję Palette za pomocą metody from(Bitmap bitmap), aby najpierw utworzyć Palette.Builder z Bitmap.

Kreator może generować paletę synchronicznie lub asynchronicznie. Jeśli chcesz utworzyć paletę na tym samym wątku, na którym wywoływana jest metoda, użyj synchronicznego generowania palety. Jeśli generujesz paletę asynchronicznie w innym wątku, użyj metody onGenerated(), aby uzyskać dostęp do palety natychmiast po jej utworzeniu.

W poniższym fragmencie kodu znajdziesz przykładowe metody dla obu typów generowania palet:

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 chcesz stale generować palety dla posortowanej listy obrazów lub obiektów, rozważ przechowywanie w pamięci podręcznej instancji Palette, aby uniknąć spowolnienia działania interfejsu. Nie twórz palet w głównym wątku.

Dostosowywanie palety

Opcja Palette.Builder umożliwia dostosowanie palety przez wybranie liczby kolorów w wygenerowanej palecie, obszaru obrazu, którego builder używa do wygenerowania palety, oraz kolorów, które mają się w niej znaleźć. Możesz na przykład odfiltrować kolor czarny lub upewnić się, że kreator używa tylko górnej połowy obrazu do wygenerowania palety.

Dopasuj 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 wynikającej palecie. Podaj własną Palette.Filter i zmodyfikuj jej metodę isAllowed(), aby określić, które kolory mają być odfiltrowywane 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 krajobrazów optymalne wartości wahają się od 8 do 16, a zdjęcia z twarzami zwykle mają wartości od 24 do 32. Wygenerowanie palet z większą liczbą kolorów w funkcji Palette.Builder trwa dłużej.
setRegion()
Ta metoda wskazuje obszar bitmapy, którego kreator używa podczas tworzenia palety. Tej metody możesz używać tylko do generowania palety z obrazu bitmapowego. Nie wpływa ona na oryginalny obraz.
addTarget()
Ta metoda umożliwia dopasowanie kolorów przez dodanie do kreatora profilu kolorówTarget. Jeśli domyślna Target jest niewystarczająca, doświadczeni deweloperzy mogą utworzyć własną Target, korzystając z Target.Builder.

Wyodrębnij profile kolorów

Biblioteka Paleta na podstawie standardów Material Design wyodrębnia z obrazu najczęściej używane profile kolorów. Każdy profil jest definiowany przez Target, a kolory wyodrębnione z obrazu bitmapy są oceniane na podstawie nasycenia, luminacji i liczby pikseli (liczby pikseli w bitmapie reprezentowanych przez kolor). W przypadku każdego profilu kolor o najlepszym wyniku definiuje 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ą opcji Palette.Builder. Wyodrębnienie większej liczby kolorów zapewnia więcej potencjalnych dopasowań dla każdego profilu kolorów, ale powoduje też wydłużenie czasu generowania palety przez Palette.Builder.

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

  • Jasny i żywy
  • Barwny
  • Jasne
  • Lekko wyciszone
  • Wyciszone
  • Ciemny wyciszony

Każda z metod get<Profile>Color()Palette zwraca kolor z paleta powiązanej z danym profilem, gdzie <Profile> jest zastąpione nazwą jednego z 6 profili kolorów. Na przykład metoda uzyskania profilu kolorów ciemny żywy to getDarkVibrantColor(). Ponieważ nie wszystkie obrazy zawierają wszystkie profile kolorów, podaj domyślny kolor do zwrócenia.

Na rysunku 1. widać zdjęcie i odpowiednie profile kolorów z metod get<Profile>Color().

Obraz pokazujący zachód słońca po lewej stronie i wyodrębnioną paletę kolorów po prawej.
Rysunek 1. Przykładowy obraz i wyodrębnione profile kolorów przy założonym domyślnym maksymalnym (16) kolorze palety.

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

Klasa Palette generuje też obiekty Palette.Swatch dla każdego profilu kolorów. Obiekty Palette.Swatch zawierają powiązany kolor dla danego profilu oraz jego populację w pikselach.

Palety mają dodatkowe metody dostępu do dodatkowych informacji o profilu kolorów, takich jak wartości HSL i populacja pikseli. Możesz użyć próbek, aby utworzyć bardziej kompleksowe schematy kolorów i motywy aplikacji, korzystając z metod getBodyTextColor()getTitleTextColor(). Te metody zwracają kolory odpowiednie do użycia w przypadku koloru próbki.

Każda metoda get<Profile>Swatch() z Palette zwraca próbkę powiązaną z danym profilem, przy czym <Profile> jest zastępowana nazwą jednego z 6 profili kolorów. Chociaż metody get<Profile>Swatch() palety nie wymagają domyślnych parametrów wartości, zwracają wartość null, jeśli danego profilu nie ma na obrazie. Dlatego przed użyciem próbki upewnij się, że nie ma ona wartości null. Na przykład poniższy kod pobiera kolor tekstu tytułu z palety, jeśli próbka koloru Kolorowa 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 na palecie, metoda getSwatches() zwraca listę wszystkich próbek wygenerowanych na podstawie obrazu, w tym standardowych 6 profili kolorów.

Ten fragment kodu korzysta z metod z poprzednich fragmentów kodu, aby synchronicznie generować paletę, pobierać jej żywe próbki i zmieniać kolory paska narzędzi, tak aby pasowały do obrazu bitmapowego. Ilustracja 2 przedstawia uzyskany 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 tekstem TitleTextColor w środku
Rysunek 2. Przykładowy obraz z paskiem narzędzi w żywych kolorach oraz odpowiednim kolorem tekstu tytułu.