Farben mit der Palette API auswählen

Ein gutes visuelles Design ist für eine erfolgreiche App unerlässlich und Farbschemata sind ein wichtiger Bestandteil des Designs. Die Palettenbibliothek ist eine Jetpack-Bibliothek, mit der markante Farben aus Bildern extrahiert werden, um visuell ansprechende Apps zu erstellen.

Mit der Palettenbibliothek können Sie Layoutthemen entwerfen und benutzerdefinierte Farben auf visuelle Elemente in Ihrer App anwenden. So können Sie beispielsweise eine farblich abgestimmte Titelkarte für einen Song basierend auf dem Albumcover erstellen oder die Symbolleiste einer App anpassen, wenn sich das Hintergrundbild ändert. Das Palette-Objekt bietet Zugriff auf die Farben in einem Bitmap-Bild und sechs Hauptfarbprofile aus der Bitmap, die Ihre Designentscheidungen beeinflussen können.

Bibliothek einrichten

Wenn Sie die Palettenbibliothek verwenden möchten, fügen Sie Folgendes zu build.gradle hinzu:

Kotlin

android {
    compileSdkVersion(33)
    ...
}

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

Groovy

android {
    compileSdkVersion 33
    ...
}

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

Palette erstellen

Mit einem Palette-Objekt haben Sie Zugriff auf die Primärfarben in einem Bild sowie auf die entsprechenden Farben für eingeblendeten Text. Mit Paletten können Sie den Stil Ihrer App entwerfen und das Farbschema Ihrer App dynamisch anhand eines bestimmten Quellbilds ändern.

Um eine Palette zu erstellen, müssen Sie zuerst eine Palette.Builder aus einer Bitmap instanziieren. Mit Palette.Builder können Sie die Palette dann anpassen, bevor Sie sie generieren. In diesem Abschnitt wird die Palettenerstellung und -anpassung aus einem Bitmapbild beschrieben.

Paletten-Instanz generieren

Erstellen Sie eine Palette-Instanz mit der Methode from(Bitmap bitmap), um zuerst eine Palette.Builder aus einer Bitmap zu erstellen.

Der Builder kann die Palette synchron oder asynchron generieren. Verwenden Sie die synchrone Palettenerstellung, wenn Sie die Palette im selben Thread wie die aufgerufene Methode erstellen möchten. Wenn Sie die Palette asynchron in einem anderen Thread generieren, verwenden Sie die Methode onGenerated(), um sofort nach dem Erstellen auf die Palette zuzugreifen.

Das folgende Code-Snippet enthält Beispielmethoden für beide Arten der Palettenerstellung:

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

Wenn Sie kontinuierlich Paletten für eine sortierte Liste von Bildern oder Objekten generieren müssen, sollten Sie die Palette-Instanzen im Cache speichern, um eine langsame UI-Leistung zu vermeiden. Erstelle die Paletten nicht in deinem Hauptthread.

Palette anpassen

Mit der Palette.Builder können Sie die Palette anpassen. Wählen Sie dazu aus, wie viele Farben die resultierende Palette enthalten soll, welchen Bereich Ihres Bildes der Builder zum Generieren der Palette verwendet und welche Farben in der Palette enthalten sein sollen. Sie können beispielsweise die Farbe Schwarz herausfiltern oder festlegen, dass der Builder nur die obere Hälfte eines Bildes verwendet, um die Palette zu generieren.

Mit den folgenden Methoden der Klasse Palette.Builder können Sie die Größe und Farben der Palette optimieren:

addFilter()
Mit dieser Methode wird ein Filter hinzugefügt, der angibt, welche Farben in der resultierenden Palette zulässig sind. Geben Sie Ihre eigene Palette.Filter an und ändern Sie die isAllowed()-Methode, um festzulegen, welche Farben aus der Palette herausgefiltert werden.
maximumColorCount()
Mit dieser Methode wird die maximale Anzahl von Farben in Ihrer Palette festgelegt. Der Standardwert ist 16. Der optimale Wert hängt vom Quellbild ab. Für Landschaftsaufnahmen liegen die optimalen Werte zwischen 8 und 16, während Bilder mit Gesichtern in der Regel Werte zwischen 24 und 32 haben. Für Paletten mit mehr Farben benötigt die Palette.Builder mehr Zeit.
setRegion()
Mit dieser Methode wird angegeben, welchen Bereich der Bitmap der Builder beim Erstellen der Palette verwendet. Diese Methode kann nur verwendet werden, wenn die Palette aus einer Bitmap generiert wird. Sie hat keine Auswirkungen auf das Originalbild.
addTarget()
Mit dieser Methode können Sie Ihre eigene Farbabstimmung vornehmen, indem Sie dem Builder ein Target-Farbprofil hinzufügen. Wenn die Standard-Target nicht ausreicht, können erfahrene Entwickler mithilfe einer Target.Builder eine eigene Target erstellen.

Farbprofile extrahieren

Basierend auf den Standards von Material Design extrahiert die Palettenbibliothek häufig verwendete Farbprofile aus einem Bild. Jedes Profil wird durch eine Target definiert. Die aus dem Bitmap-Bild extrahierten Farben werden anhand von Sättigung, Leuchtkraft und Population (Anzahl der Pixel in der Bitmap, die durch die Farbe dargestellt werden) mit jedem Profil verglichen. Für jedes Profil wird das Farbprofil für das jeweilige Bild durch die Farbe mit der besten Bewertung definiert.

Standardmäßig enthält ein Palette-Objekt 16 Hauptfarben aus einem bestimmten Bild. Beim Generieren der Palette können Sie die Anzahl der Farben mithilfe von Palette.Builder anpassen. Wenn Sie mehr Farben extrahieren, gibt es mehr potenzielle Übereinstimmungen für jedes Farbprofil. Das führt jedoch auch dazu, dass Palette.Builder beim Generieren der Palette länger benötigt.

Die Palettenbibliothek versucht, die folgenden sechs Farbprofile zu extrahieren:

  • Leuchtend
  • Leuchtend
  • Dunkel – dynamisch
  • Leuchtend gedimmt
  • stummgeschaltet,
  • Dunkel (gedämpft)

Jede der get<Profile>Color()-Methoden in Palette gibt die Farbe in der Palette zurück, die mit dem jeweiligen Profil verknüpft ist. Dabei wird <Profile> durch den Namen eines der sechs Farbprofile ersetzt. Die Methode zum Abrufen des Farbprofils „Dunkel, leuchtend“ lautet beispielsweise getDarkVibrantColor(). Da nicht alle Bilder alle Farbprofile enthalten, geben Sie eine Standardfarbe an, die zurückgegeben werden soll.

Abbildung 1 zeigt ein Foto und die zugehörigen Farbprofile aus den get<Profile>Color()-Methoden.

Ein Bild mit einem Sonnenuntergang auf der linken Seite und der extrahierten Farbpalette auf der rechten Seite
Abbildung 1. Beispielbild und die daraus extrahierten Farbprofile mit der standardmäßigen maximalen Farbanzahl (16) für die Palette.

Farbmuster verwenden, um Farbschemas zu erstellen

Die Palette-Klasse generiert außerdem Palette.Swatch-Objekte für jedes Farbprofil. Palette.Swatch-Objekte enthalten die zugehörige Farbe für dieses Profil sowie die Häufigkeit der Farbe in Pixeln.

Swatches bieten zusätzliche Methoden, um auf weitere Informationen zum Farbprofil zuzugreifen, z. B. HSL-Werte und Pixelbelegung. Mithilfe von Farbmustern können Sie mit den Methoden getBodyTextColor() und getTitleTextColor() umfassendere Farbschemata und App-Designs erstellen. Diese Methoden geben Farben zurück, die sich für die Verwendung über der Farbe des Farbmusters eignen.

Jede get<Profile>Swatch()-Methode aus Palette gibt das mit dem jeweiligen Profil verknüpfte Farbmuster zurück. Dabei wird <Profile> durch den Namen eines der sechs Farbprofile ersetzt. Für die get<Profile>Swatch()-Methoden der Palette sind zwar keine Standardwertparameter erforderlich, sie geben aber null zurück, wenn das betreffende Profil im Bild nicht vorhanden ist. Prüfen Sie daher, ob ein Swatch nicht null ist, bevor Sie es verwenden. Im folgenden Code wird beispielsweise die Textfarbe des Titels aus einer Palette abgerufen, wenn das Swatch für „Lebhaft“ nicht null ist:

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

Um auf alle Farben in einer Palette zuzugreifen, gibt die Methode getSwatches() eine Liste aller aus einem Bild generierten Farbmuster zurück, einschließlich der sechs Standardfarbprofile.

Im folgenden Code-Snippet werden die Methoden aus den vorherigen Code-Snippets verwendet, um synchron eine Palette zu generieren, das lebendige Farbmuster abzurufen und die Farben einer Symbolleiste an das Bitmap-Bild anzupassen. Abbildung 2 zeigt das resultierende Bild und die Symbolleiste.

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);
}
Ein Bild mit einem Sonnenuntergang und einer Symbolleiste mit „TitleTextColor“
Abbildung 2. Beispielbild mit einer farbenfrohen Symbolleiste und der entsprechenden Textfarbe für den Titel