Wybieranie kolorów za pomocą interfejsu Palette API

Dobry projekt wizualny to podstawa skutecznej aplikacji, a schemat kolorów to podstawowy element projektowania. Biblioteka palet to biblioteka Jetpack, która wyodrębnia wyraźne kolory z obrazów, aby tworzyć atrakcyjne wizualnie aplikacje.

Za pomocą biblioteki palet możesz projektować motywy układu i stosować niestandardowe kolory do elementów wizualnych w aplikacji. Możesz na przykład użyć palety, aby utworzyć kartę tytułową utworu o skorelowanej kolorystyce na podstawie okładki albumu lub dostosować kolor paska narzędzi aplikacji, gdy zmieni się jego obraz tła. Obiekt Palette zapewnia dostęp do kolorów obrazu Bitmap, a jednocześnie udostępnia 6 głównych profili kolorów z bitmapy, na podstawie których można dokonywać wyborów.

Skonfiguruj bibliotekę

Aby korzystać z biblioteki palet, dodaj do build.gradle:

Kotlin

android {
    compileSdkVersion(33)
    ...
}

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

Odlotowy

android {
    compileSdkVersion 33
    ...
}

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

Utwórz paletę

Obiekt Palette zapewnia dostęp do kolorów podstawowych obrazu oraz odpowiadających im kolorów nałożonych na tekst. Za pomocą palet możesz zaprojektować styl swojej aplikacji i dynamicznie zmieniać jej schemat kolorów w zależności od obrazu źródłowego.

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

Generowanie instancji palety

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

Kreator może wygenerować paletę synchronicznie lub asynchronicznie. Jeśli chcesz utworzyć paletę w tym samym wątku, co wywoływana 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.

Poniższy fragment kodu zawiera przykładowe metody generowania palet 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 stale generować palety dla posortowanej listy obrazów lub obiektów, rozważ zapisanie w pamięci podręcznej instancji Palette, aby zapobiec spowolnieniu działania interfejsu. Nie twórz palet w wątku głównym.

Dostosuj paletę

Pole Palette.Builder pozwala dostosować paletę, wybierając, ile kolorów zawiera wynikowa paleta, jaki obszar obrazu wykorzysta do wygenerowania palety i jakie kolory są uwzględnione w palecie. Możesz na przykład odfiltrować czarny kolor lub upewnić się, że kreator wygeneruje paletę tylko z górnej połowy obrazu.

Rozmiar i kolory palety możesz dostosować 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łasny atrybut Palette.Filter i zmodyfikuj jego metodę isAllowed(), aby określić, które kolory są filtrowane z palety.
maximumColorCount()
Ta metoda ustawia maksymalną liczbę kolorów w palecie. Wartość domyślna to 16, a optymalna zależy od obrazu źródłowego. W przypadku orientacji poziomej optymalne wartości mieszczą się w przedziale od 8 do 16, a w przypadku zdjęć z twarzami – zwykle z przedziału 24–32. Wygenerowanie palet z większą liczbą kolorów przez Palette.Builder trwa dłużej.
setRegion()
Ta metoda wskazuje obszar bitmapy używany przez konstruktora podczas tworzenia palety. Tej metody możesz używać tylko podczas generowania palety z bitmapy. Nie ma ona wpływu na oryginalny obraz.
addTarget()
Ta metoda pozwala Ci przeprowadzić własne dopasowanie kolorów, dodając do konstruktora profil kolorów Target. Jeśli domyślna wartość Target jest niewystarczająca, zaawansowani programiści mogą tworzyć własne Target za pomocą Target.Builder.

Wyodrębnij profile kolorów

Na podstawie standardów Material Design biblioteka palet wyodrębnia często używane profile kolorów z obrazu. Każdy profil jest definiowany za pomocą Target, a kolory wyodrębnione z obrazu bitmapy są oceniane w odniesieniu do każdego profilu na podstawie nasycenia, luminancji i populacji (liczby pikseli w bitmacie reprezentowanych przez kolor). W przypadku każdego profilu kolor z najlepszym wynikiem określa profil kolorów danego zdjęcia.

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

Biblioteka paleta podejmuje próbę wyodrębnienia następujących 6 profili kolorów:

  • Jasny żywy
  • Barwny
  • Ciemny żywy
  • Przygaszone światło
  • wyciszone,
  • Ciemny wyciszony

Każda z metod get<Profile>Color() w Palette zwraca kolor z palety powiązanej z tym profilem, przy czym <Profile> jest zastępowane nazwą jednego z 6 profili kolorów. Na przykład metodą uzyskiwania profilu ciemnych kolorów jest getDarkVibrantColor(). Nie wszystkie obrazy zawierają wszystkie profile kolorów, dlatego wybierz kolor domyślny.

Rysunek 1 przedstawia zdjęcie i odpowiadające mu profile kolorów z metod get<Profile>Color().

Obraz przedstawiający zachód słońca po lewej stronie, a po prawej – wyodrębnioną paletę kolorów.
Rysunek 1. Przykładowy obraz i wyodrębnione profile kolorów z uwzględnieniem domyślnej maksymalnej liczby kolorów dla palety (16).

Używaj próbek do tworzenia schematów kolorów

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

Próbki mają dodatkowe metody uzyskiwania dodatkowych informacji o profilu kolorów, np. wartości HSL i populację pikseli. Możesz użyć próbek, aby za pomocą metod getBodyTextColor() i getTitleTextColor() tworzyć bardziej szczegółowe schematy kolorów i motywy aplikacji. Metody te zwracają kolory odpowiednie do zastosowania w przypadku koloru próbki.

Każda metoda get<Profile>Swatch() z Palette zwraca próbkę powiązaną z tym profilem, gdzie <Profile> jest zastępowana nazwą jednego z 6 profili kolorów. Chociaż metody get<Profile>Swatch() palety nie wymagają parametrów wartości domyślnej, zwracają wartość null, jeśli na obrazie nie ma określonego profilu. Dlatego przed użyciem próbnika sprawdź, czy nie ma on wartości null. Jeśli na przykład próbnik Barwnych kolorów nie ma wartości null, ten kod pobiera kolor tekstu tytułu z palety:

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 z palety, metoda getSwatches() zwraca listę wszystkich próbek wygenerowanych z obrazu, w tym 6 standardowych profili kolorów.

Następujący fragment kodu wykorzystuje metody z poprzednich fragmentów kodu do synchronicznego generowania palety, pobierania próbek kolorów w kolorach paska narzędzi i zmieniania kolorów paska narzędzi tak, aby pasował do obrazu bitmapy. Rysunek 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 wewnątrz
Rysunek 2. Przykładowy obraz z jaskrawym paskiem narzędzi i odpowiednim kolorem tekstu tytułu.