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 Sie bei Ihren Designentscheidungen unterstützen.

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.

Instanziieren Sie zuerst eine Palette.Builder aus einer Bitmap, um eine Palette zu erstellen. Mit Palette.Builder können Sie die Palette dann anpassen, bevor Sie sie generieren. In diesem Abschnitt wird die Erstellung und Anpassung von Paletten mithilfe eines Bitmapbilds beschrieben.

Palette-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 Erstellung von Paletten, wenn Sie die Palette in demselben 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 Generierung von Paletten:

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 Palette.Builder können Sie Ihre Palette anpassen. Dazu wählen Sie aus, wie viele Farben die Palette enthält, welchen Bereich Ihres Images der Builder zum Generieren der Palette verwendet und welche Farben in der Palette enthalten sind. Sie können beispielsweise die Farbe Schwarz herausfiltern oder festlegen, dass der Builder nur die obere Hälfte eines Bilds 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. Mit Palette.Builder dauert es länger, um Vorlagen mit mehr Farben zu generieren.
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 der Standardwert für Target nicht ausreicht, können fortgeschrittene Entwickler ihre eigene Target mit einer Target.Builder 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 Erstellen der Palette können Sie die Anzahl der Farben mit 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:

  • Hell und 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 dem jeweiligen Profil zugeordnet ist. Dabei wird <Profile> durch den Namen eines der sechs Farbprofile ersetzt. Beispielsweise lautet die Methode zum Abrufen des Farbprofils „Dark Lively“ getDarkVibrantColor(). Da nicht alle Bilder alle Farbprofile enthalten, sollten Sie eine Standardfarbe angeben, 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 Grundgesamtheit der Farbe in Pixeln.

Swatches bieten zusätzliche Methoden, um auf weitere Informationen zum Farbprofil zuzugreifen, z. B. HSL-Werte und Pixelbelegung. Mithilfe von Muster können Sie mithilfe der Methoden getBodyTextColor() und getTitleTextColor() umfassendere Farbschemas und App-Designs erstellen. Diese Methoden geben Farben zurück, die anstelle der Farbe des Musters verwendet werden können.

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.

Das folgende Code-Snippet verwendet die Methoden aus den vorherigen Code-Snippets, um synchron eine Palette zu generieren, ein lebhaftes Muster zu erhalten und die Farben einer Symbolleiste so zu ändern, dass sie dem Bitmapbild entsprechen. 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