Выбор цветов с помощью Palette API

Хороший визуальный дизайн необходим для успешного приложения, а цветовые схемы являются основным компонентом дизайна. Библиотека Palette – это библиотека Jetpack, которая извлекает основные цвета из изображений, чтобы создавать визуально привлекательные приложения.

С помощью библиотеки Palette можно создавать темы макетов и применять пользовательские цвета к визуальным элементам приложения. Например, вы можете использовать палитру, чтобы создать заставку для песни, которая будет сочетаться по цвету с обложкой альбома, или настроить цвет панели инструментов приложения при изменении фонового изображения. Объект Palette предоставляет доступ к цветам изображения Bitmap, а также к шести основным цветовым профилям из растрового изображения, которые можно использовать в дизайне.

Как настроить библиотеку

Чтобы использовать библиотеку Palette, добавьте в файл build.gradle следующий код:

Kotlin

android {
    compileSdkVersion(36)
    ...
}

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

Яркий

android {
    compileSdkVersion 36
    ...
}

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

Создать палитру

Объект Palette предоставляет доступ к основным цветам изображения, а также к соответствующим цветам наложенного текста. Используйте палитры, чтобы разработать стиль приложения и динамически менять его цветовую схему на основе заданного исходного изображения.

Чтобы создать палитру, сначала создайте экземпляр Palette.Builder из Bitmap. Затем вы можете использовать Palette.Builder, чтобы настроить палитру перед ее созданием. В этом разделе описывается создание и настройка палитры на основе растрового изображения.

Создание экземпляра Palette

Создайте экземпляр Palette с помощью метода from(Bitmap bitmap), чтобы сначала создать Palette.Builder из Bitmap.

Конструктор может генерировать палитру синхронно или асинхронно. Используйте синхронную генерацию палитры, если вы хотите создать палитру в том же потоке, что и вызываемый метод. Если вы генерируете палитру асинхронно, в другом потоке, используйте метод onGenerated(), чтобы получить доступ к палитре сразу после ее создания.

В следующем фрагменте кода показаны примеры методов для обоих типов генерации палитры:

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

Если вам нужно постоянно генерировать палитры для отсортированного списка изображений или объектов, рассмотрите возможность кэширования экземпляров Palette, чтобы предотвратить медленную работу пользовательского интерфейса. Не создавайте палитры в основном потоке.

Настройте палитру

Palette.Builder позволяет настроить палитру, выбрав количество цветов в ней, область изображения, которая используется для создания палитры, и цвета, которые в нее входят. Например, вы можете исключить черный цвет или сделать так, чтобы конструктор использовал для создания палитры только верхнюю половину изображения.

Вы можете настроить размер и цвета палитры с помощью следующих методов класса Palette.Builder:

addFilter()
Этот метод добавляет фильтр, который указывает, какие цвета разрешены в результирующей палитре. Передайте собственный объект Palette.Filter и измените его метод isAllowed(), чтобы определить, какие цвета будут отфильтрованы из палитры.
maximumColorCount()
Этот метод задает максимальное количество цветов в палитре. Значение по умолчанию – 16, а оптимальное значение зависит от исходного изображения. Для пейзажей оптимальные значения находятся в диапазоне от 8 до 16, а для портретов – от 24 до 32. Чем больше цветов в палитре, тем дольше Palette.Builder будет ее генерировать.
setRegion()
Этот метод указывает, какую область битовой карты использует конструктор при создании палитры. Этот метод можно использовать только при создании палитры из битовой карты, и он не влияет на исходное изображение.
addTarget()
Этот метод позволяет выполнить собственное сопоставление цветов, добавив в конструктор цветовой профиль. Target Если стандартного класса Target недостаточно, опытные разработчики могут создать собственный класс Target с помощью Target.Builder.

Извлечь цветовые профили

Библиотека Palette извлекает из изображения часто используемые цветовые профили на основе стандартов Material Design. Каждый профиль определяется Target, а цвета, извлеченные из растрового изображения, оцениваются по каждому профилю на основе насыщенности, яркости и количества пикселей в растровом изображении, представленном цветом. Для каждого профиля цвет с наилучшей оценкой определяет этот цветовой профиль для данного изображения.

По умолчанию объект Palette содержит 16 основных цветов из заданного изображения. При создании палитры вы можете настроить количество цветов с помощью Palette.Builder. Чем больше цветов извлекается, тем больше потенциальных совпадений для каждого цветового профиля, но тем дольше Palette.Builder генерирует палитру.

Библиотека Palette пытается извлечь следующие шесть цветовых профилей:

  • Светлый яркий
  • Сочно
  • Темная сочная
  • Светло-серый
  • Без звука
  • Темный приглушенный

Каждый из методов get<Profile>Color() в Palette возвращает цвет в палитре, связанной с определенным профилем, где <Profile> заменяется названием одного из шести цветовых профилей. Например, чтобы получить темный яркий цветовой профиль, используется метод getDarkVibrantColor(). Поскольку не все изображения содержат все цветовые профили, укажите цвет по умолчанию, который будет возвращаться.

На рисунке 1 показана фотография и соответствующие ей цветовые профили, полученные с помощью методов get<Profile>Color().

Изображение, на котором слева показан закат, а справа – извлеченная палитра.
Рисунок 1. Пример изображения и извлеченных из него цветовых профилей с учетом максимального количества цветов по умолчанию (16) для палитры.

Как создавать цветовые схемы с помощью образцов

Класс Palette также генерирует объекты Palette.Swatch для каждого цветового профиля. Объекты Palette.Swatch содержат цвет, связанный с этим профилем, а также количество пикселей этого цвета.

Образцы имеют дополнительные методы для доступа к дополнительной информации о цветовом профиле, такой как значения HSL и количество пикселей. С помощью образцов можно создавать более сложные цветовые схемы и темы приложений, используя методы getBodyTextColor() и getTitleTextColor(). Эти методы возвращают цвета, подходящие для использования поверх цвета образца.

Каждый метод get<Profile>Swatch() из Palette возвращает образец, связанный с определенным профилем, где <Profile> заменяется названием одного из шести цветовых профилей. Хотя методы get<Profile>Swatch() палитры не требуют параметров значения по умолчанию, они возвращают null, если этот конкретный профиль не существует в изображении. Поэтому перед использованием образца убедитесь, что он не равен null. Например, следующий код получает цвет текста заголовка из палитры, если образец Vibrant не равен 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();
    // ...
}

Чтобы получить доступ ко всем цветам палитры, метод getSwatches() возвращает список всех образцов, сгенерированных на основе изображения, включая шесть стандартных цветовых профилей.

В следующем фрагменте кода используются методы из предыдущих фрагментов кода для синхронной генерации палитры, получения ее яркого образца и изменения цветов панели инструментов в соответствии с растровым изображением. На рисунке 2 показано полученное изображение и панель инструментов.

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);
}
Изображение, на котором показан закат и панель инструментов с TitleTextColor внутри
Рисунок 2. Пример изображения с яркой панелью инструментов и соответствующим цветом текста заголовка.