Android 调色板颜色之间的差异

Differences between Android Palette colors

编辑

为了更好地感受 Android 调色板 class,我决定制作一个简单的应用程序来测试它的一些功能 - 如果您有兴趣,可以在Play 商店:https://play.google.com/store/apps/details?id=com.tonyw.sampleapps.palettecolorextraction. Basically it just has images and the colors that the Palette class extracts (mentioned below), and you can add your own images to test as well. You can find my source code on Github: https://github.com/tony-w/PaletteColorExtraction

截图

原版post

谁能描述一下可以使用 Android's Palette class 从位图中提取的颜色之间的差异?

仅仅是柔和的颜色比鲜艳的颜色暗淡吗?深色和浅色是否应该分别更好地匹配 Lollipop 的深色和浅色材质设计主题?

这真是个好问题。如果您查看 source code,您会发现根据亮度、饱和度和总体(图像中有多少像素)的目标范围,通过分析图像上像素的 HSL 颜色配置文件选择不同的样本由样本表示)。它使用加权平均计算,优先考虑亮度,然后是饱和度,然后是人口

一般来说,鲜艳的颜色比柔和的颜色更饱和,深色更深,浅色更亮。具体用哪个,看你想要的整体效果。

Chris Banes wrote in his blog "Vibrant and Dark Vibrant are the ones that developers will use mostly" 但实际上并没有那么简单。

我发现的一个例子是 Google IO 2014 中 Romain Guy's sample app 中的 applyPalette 方法,尽管代码假定会找到各种样本(可能是因为他正在与已知图像)。

根据图像的不同,可能找不到某些样本类型,因此请务必在代码中考虑到这种可能性。

例如,您可以尝试按特定顺序从调色板中获取色板,例如对于 Dark 主题,您可以尝试使用 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 值也是可访问的,因此您可以编写类似的例程来选择,例如,不是 主色的最饱和样本。


使用自定义目标

另一件我发现有用的事情是在 Palette.Target 中定义的 6 个目标之外定义一些自定义目标,具有不同的权重和目标亮度和饱和度值,以增加找到的机会有用的颜色。

例如,您可以要求 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 拒绝非常接近黑色或白色的颜色,以及我认为指的是 等时的颜色 "very near to the red I line"红盲色盲患者难以识别的颜色

我的理论是它拒绝接近白色和接近黑色的颜色,以帮助防止这些颜色在饱和度权重很高时被选为 "saturated" 颜色。

然而,此过滤器的结果是,对于完全由几乎白色 and/or 几乎黑色像素组成的图像,以及避免选择带有粉红色调的颜色的趋势,将找不到样本。

但是,可以使用 Palette.Builder.clearFilters() 删除此过滤器,并使用 Palette.Builder.addFilter() 添加您自己的过滤器。

在我的代码中,如果第一次尝试没有 return 任何样本,我选择第二次尝试生成调色板:

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

链接尝试在大多数情况下保留了默认过滤器的有用性,但仍然允许您找到默认会完全拒绝的图像样本。