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

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

You can use the Palette library to design layout themes and apply custom colors to visual elements in your app. For example, you can use a palette to create a color-coordinated title card for a song based on its album cover or to adjust an app's toolbar color when its background image changes. The Palette object gives you access to the colors in a Bitmap image while also providing six main color profiles from the bitmap to inform your design choices .

Настройте библиотеку

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

Котлин

android {
    compileSdkVersion(33)
    ...
}

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

Круто

android {
    compileSdkVersion 33
    ...
}

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

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

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

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

Создать экземпляр палитры

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

The builder can generate the palette synchronously or asynchronously. Use synchronous palette generation if you want to create the palette on the same thread as the method being called. If you generate the palette asynchronously, on a different thread, use the onGenerated() method to access the palette immediately after it is created.

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

Котлин

// 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.
    }
}

Ява

// 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 .

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

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

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

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

  • Яркий свет
  • Яркий
  • Темно-яркий
  • Приглушенный свет
  • Приглушенный
  • Темный приглушенный

Каждый из методов get< Profile >Color() в Palette возвращает цвет из палитры, связанной с этим профилем, где < Profile > заменяется именем одного из шести цветовых профилей. Например, метод для получения цветового профиля Dark Vibrant — 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:

Котлин

val vibrant = myPalette.vibrantSwatch
// In Kotlin, check for null before accessing properties on the vibrant swatch.
val titleColor = vibrant?.titleTextColor

Ява

Palette.Swatch vibrant = myPalette.getVibrantSwatch();
if(vibrant != null){
    int titleColor = vibrant.getTitleTextColor();
    // ...
}

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

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

Котлин

// 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))
    }
}

Ява

// 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. Пример изображения с яркой цветной панелью инструментов и соответствующим цветом текста заголовка.