Farben mit der Palette API auswählen

Ein gutes visuelles Design ist für eine erfolgreiche App unerlässlich und Farbschemas sind ein wichtiger Bestandteil des Designs. Die Palette-Bibliothek ist eine Jetpack-Bibliothek, mit der Sie markante Farben aus Bildern extrahieren können, um visuell ansprechende Apps zu erstellen.

Mit der Palette-Bibliothek können Sie Layoutdesigns erstellen und benutzerdefinierte Farben auf visuelle Elemente in Ihrer App anwenden. Sie können beispielsweise eine Palette verwenden, um eine farblich abgestimmte Titelseite für einen Song basierend auf dem Albumcover zu erstellen oder die Farbe der Symbolleiste einer App anzupassen, wenn sich das Hintergrundbild ändert. Das Palette Objekt bietet Zugriff auf die Farben in einem Bitmap-Bild und stellt außerdem sechs Hauptfarbprofile aus der Bitmap zur Verfügung, um Ihre Designentscheidungen zu treffen.

Bibliothek einrichten

Wenn Sie die Palette-Bibliothek 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

Über ein Palette-Objekt haben Sie Zugriff auf die Primärfarben in einem Bild sowie auf die entsprechenden Farben für überlagerten Text. Mit Paletten können Sie das Design Ihrer App festlegen und das Farbschema Ihrer App basierend auf einem bestimmten Quellbild dynamisch ändern.

Um eine Palette zu erstellen, müssen Sie zuerst eine Palette.Builder aus einer Bitmap instanziieren. Sie können dann Palette.Builder verwenden, um die Palette vor dem Generieren anzupassen. In diesem Abschnitt wird beschrieben, wie Sie eine Palette aus einem Bitmapbild generieren und anpassen.

Palette-Instanz generieren

Generieren 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 Palettengenerierung, 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 Palettengenerierung:

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 zwischenspeichern, um eine langsame UI-Leistung zu vermeiden. Erstellen Sie die Paletten nicht im Haupt-Thread.

Palette anpassen

Mit Palette.Builder können Sie Ihre Palette anpassen, indem Sie festlegen, 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 sind. Sie können beispielsweise die Farbe Schwarz herausfiltern oder dafür sorgen, dass der Builder nur die obere Hälfte eines Bildes verwendet, um Ihre Palette zu generieren.

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

addFilter()
Mit dieser Methode wird ein Filter hinzugefügt, der angibt, welche Farben in der resultierenden Palette zulässig sind. Übergeben Sie Ihre eigene Palette.Filter und ändern Sie die zugehörige 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. Bei Landschaftsaufnahmen liegen die optimalen Werte zwischen 8 und 16, bei Bildern mit Gesichtern in der Regel zwischen 24 und 32. Die Palette.Builder braucht länger, um Paletten mit mehr Farben zu generieren.
setRegion()
Diese Methode gibt an, welchen Bereich der Bitmap der Builder beim Erstellen der Palette verwendet. Sie können diese Methode nur verwenden, wenn Sie die Palette aus einer Bitmap generieren. Das Originalbild wird dadurch nicht beeinflusst.
addTarget()
Mit dieser Methode können Sie einen eigenen Farbabgleich durchführen, indem Sie dem Builder ein Target-Farbprofil hinzufügen. Wenn die Standard-Target nicht ausreicht, können fortgeschrittene Entwickler mit einem Target.Builder eine eigene Target erstellen.

Farbprofile extrahieren

Die Palette-Bibliothek extrahiert basierend auf den Standards von Material Design häufig verwendete Farbprofile aus einem Bild. Jedes Profil wird durch ein Target definiert. Aus dem Bitmap-Bild extrahierte Farben werden anhand von Sättigung, Luminanz und Population (Anzahl der Pixel im Bitmap, die durch die Farbe dargestellt werden) mit jedem Profil verglichen. Für jedes Profil wird die Farbe mit der besten Punktzahl als Farbprofil für das jeweilige Bild festgelegt.

Standardmäßig enthält ein Palette-Objekt 16 Primärfarben aus einem bestimmten Bild. Beim Generieren der Palette können Sie die Anzahl der Farben mit dem Palette.Builder anpassen. Wenn Sie mehr Farben extrahieren, gibt es mehr potenzielle Übereinstimmungen für jedes Farbprofil. Allerdings dauert es dann auch länger, bis Palette.Builder die Palette generiert.

Die Palette-Bibliothek versucht, die folgenden sechs Farbprofile zu extrahieren:

  • Leicht dynamisch
  • Leuchtend
  • Dunkel und dynamisch
  • Leicht gedämpft
  • 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 und lebendig“ ist 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 entsprechenden 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. Ein Beispielbild und die daraus extrahierten Farbprofile bei der standardmäßigen maximalen Anzahl von Farben (16) für die Palette.

Farbmuster zum Erstellen von Farbschemas verwenden

Die Klasse Palette generiert auch Palette.Swatch-Objekte für jedes Farbprofil. Palette.Swatch-Objekte enthalten die zugehörige Farbe für dieses Profil sowie die Anzahl der Pixel, in denen die Farbe vorkommt.

Für Farbfelder gibt es zusätzliche Methoden, um auf weitere Informationen zum Farbprofil zuzugreifen, z. B. HSL-Werte und Pixelanzahl. Mit Farbfeldern können Sie mithilfe der Methoden getBodyTextColor() und getTitleTextColor() umfassendere Farbschemas und App-Designs erstellen. Diese Methoden geben Farben zurück, die für die Verwendung über der Farbe des Farbmusters geeignet sind.

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 entsprechende Profil im Bild nicht vorhanden ist. Prüfen Sie daher, ob ein Farbfeld null ist, bevor Sie es verwenden. Mit dem folgenden Code wird beispielsweise die Titelfarbe aus einer Palette abgerufen, wenn der Vibrant-Farbfeld 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();
    // ...
}

Wenn Sie auf alle Farben in einer Palette zugreifen möchten, 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, den lebendigen Farbton 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);
}
Bild eines Sonnenuntergangs und einer Symbolleiste mit TitleTextColor
Abbildung 2. Beispielbild mit einer Symbolleiste in kräftigen Farben und der entsprechenden Titelfarbe.