Различия между цветами палитры Android

17

Edit

Чтобы лучше понять класс Android Palette, я решил сделать простое приложение для тестирования некоторых его функций - если вам интересно, вы можете найти приложение в Play Store: Ссылка . В основном у него есть только изображения и цвета, которые извлекаются в классе палитры (см. Ниже), и вы можете добавить свои собственные изображения для тестирования. Вы можете найти мой исходный код в Github: Ссылка

Скриншоты

Оригинальное сообщение

Может кто-то описать различия между цветами, которые можно извлечь из растрового изображения, используя Android Класс палитры ?

  • Яркий
  • Яркий темный
  • Яркий свет
  • Отключено
  • Приглушенная тьма
  • Приглушенный свет

Это просто, что приглушенные цвета более тусклые, чем яркие цвета? Являются ли темные и светлые, чтобы лучше соответствовать темным и светлым темам дизайна Lollipop, соответственно?

    
задан Tony Wickham 26.01.2015 в 05:35
источник

1 ответ

27

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

Вообще говоря, яркие цвета более насыщены, чем приглушенные цвета, темные цвета темнее, а светлые образцы легче. Какой из них вы используете, зависит от общего эффекта, который вы хотите.

Chris Banes написал в своем блоге «Яркие и темные Vibrant - это те, которые разработчики будет использоваться в основном ", но на практике это не так просто.

Один из примеров, который я нашел, - это метод applyPalette в пример приложения Romain Guy от Google IO 2014, хотя код предполагает, что различные образцы будут найдены (возможно, потому, что он работает с известными изображениями).

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

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

Если вам нужно что-то более предсказуемое, также можно захватить наиболее представленный цвет, например:

public static Palette.Swatch getDominantSwatch(Palette palette) {
    // find most-represented swatch based on population
    return Collections.max(palette.getSwatches(), new Comparator<Palette.Swatch>() {
        @Override
        public int compare(Palette.Swatch sw1, Palette.Swatch sw2) {
            return Integer.compare(sw1.getPopulation(), sw2.getPopulation());
        }
    });
}

Значения HSL для каждого образца также доступны, поэтому вы можете написать аналогичную процедуру, чтобы выбрать, например, самый насыщенный образец, который не является доминирующим цветом.

Использование пользовательских целей

Еще одна полезная вещь - определить некоторые пользовательские цели в дополнение к 6 целям, определенным в Palette.Target , с различными значениями веса и целевого уровня и значения насыщенности, чтобы увеличить вероятность поиска полезного цвета.

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

public static final Target DOMINANT;

static {
    DOMINANT = new Target.Builder().setPopulationWeight(1f)
                                   .setSaturationWeight(0f)
                                   .setLightnessWeight(0f)
                                   .setExclusive(false)
                                   .build();
}

И вы можете получить некоторые полезные образцы, которые ставят более высокий приоритет на легкость, чем целевые фонды, такие как:

public static final Target DARK;
public static final Target LIGHT;
public static final Target NEUTRAL;

static {
    DARK = new Target.Builder().setMinimumLightness(0f)
                               .setTargetLightness(0.26f)
                               .setMaximumLightness(0.5f)
                               .setMinimumSaturation(0.1f)
                               .setTargetSaturation(0.6f)
                               .setMaximumSaturation(1f)
                               .setPopulationWeight(0.18f)
                               .setSaturationWeight(0.22f)
                               .setLightnessWeight(0.60f)
                               .setExclusive(false)
                               .build();

    LIGHT = new Target.Builder().setMinimumLightness(0.50f)
                                .setTargetLightness(0.74f)
                                .setMaximumLightness(1.0f)
                                .setMinimumSaturation(0.1f)
                                .setTargetSaturation(0.7f)
                                .setMaximumSaturation(1f)
                                .setPopulationWeight(0.18f)
                                .setSaturationWeight(0.22f)
                                .setLightnessWeight(0.60f)
                                .setExclusive(false)
                                .build();

    NEUTRAL = new Target.Builder().setMinimumLightness(0.20f)
                                  .setTargetLightness(0.5f)
                                  .setMaximumLightness(0.8f)
                                  .setMinimumSaturation(0.1f)
                                  .setTargetSaturation(0.6f)
                                  .setMaximumSaturation(1f)
                                  .setPopulationWeight(0.18f)
                                  .setSaturationWeight(0.22f)
                                  .setLightnessWeight(0.60f)
                                  .setExclusive(false)
                                  .build();
}

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

Palette.Swatch neutral = Palette.getSwatchForTarget(NEUTRAL);

Обратите внимание на фильтр по умолчанию

По умолчанию Palette имеет Palette.Filter , который отклоняет цвета, очень близкие к черному или белым, а также цвета «очень близко к красной строке I», которые, как я полагаю, относятся к изохронным цветам , которые трудны для людей с красно-слепой цветовой слепотой.

Моя теория заключается в том, что она отвергает почти белые и почти черные цвета, чтобы помочь предотвратить их выбор в качестве «насыщенных» цветов, когда насыщенность высоко взвешена.

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

Однако этот фильтр можно удалить, используя Palette.Builder.clearFilters() , и добавьте свой собственный фильтр с Palette.Builder.addFilter() .

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

Palette palette = new Palette.Builder(bitmap).addTarget(DOMINANT)
                                             .addTarget(DARK)
                                             .addTarget(LIGHT)
                                             .addTarget(NEUTRAL)
                                             .generate();
if(palette.getSwatches().isEmpty()) {
    Log.v(TAG, "Getting alternate (UNFILTERED) palette.");
    palette = new Palette.Builder(bitmap).addTarget(DOMINANT)
                                         .addTarget(DARK)
                                         .addTarget(LIGHT)
                                         .addTarget(NEUTRAL)
                                         .clearFilters() /// allow isBlack(), isWhite(), isNearRedILine()
                                         .generate();
}

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

    
ответ дан Lorne Laliberte 28.02.2015 в 00:27
  • Отличный ответ, спасибо! Также я ценю идеи для хороших резервов, когда образцы не найдены. :) –  Tony Wickham 01.03.2015 в 08:19
  • Начиная с palette-v7: 25.0.0, теперь есть метод удобства, называемый getDominantSwatch - реализация пользовательского метода больше не требуется. Остальная часть ответа все еще действительна и хороша! –  David Doyle 22.11.2016 в 11:42
  • @DavidDoyle Да, правда! Они добавили эквивалентный метод, который выбирает образец с самым высоким населением. Однако я должен признать, что в своем собственном коде я нашел более эффективным использование доминирующей цели (с массой тела 1f и другими весами 0f), поскольку он находит более доминирующий цвет в целом, вместо того, чтобы просто выбирать наиболее населенный образец среди тех которые соответствовали другим целевым критериям (VIBRANT, MUTED и т. д.). –  Lorne Laliberte 12.12.2016 в 23:40
  • @DavidDoyle Calling getDominantSwatch даст вам образец с самым высоким населением среди образцов, которые были выбраны из изображения ... тогда как использование цели определит доминирующий цвет для изображения в целом. Оба являются действительными и имеют свои применения, но я нашел, что менее ограничительный подход (с использованием цели) обычно более уместен, когда мне нужен общий доминирующий цвет, например. как временный фон изображения. –  Lorne Laliberte 12.12.2016 в 23:57