Android调色板获取不到bitmap的颜色 安卓调色板_API


前不久,就 Android 系统中的 tint 着色器 写有一篇文章,从使用到源码,详细予以阐述。从色彩的角度上来讲,Palette(调色板)似乎与之遥相呼应,所以便有了这篇:关于 Android 中的 Palette 类。

Palette 类的基本使用


利用 Palette 类能够提取一张图片或者说 BitMap 对象中较为突出的那些颜色,供开发人员使用。

这有什么用呢?这就看你怎么用啦。比如根据页面图片内容,灵活改变当前页面的 UI 主题色调。等会在后面的内容中会举个较为实用的例子。

使用 Palette 类前,需要在 build.gradle 文件中引入相应的 support 依赖包,比如当前版本:

dependencies {
    compile 'com.android.support:palette-v7:25.3.0'
}

解析图片是一个相对程序而言稍为耗时的过程,所以生成 Palette 对象的过程应该放在子线程当中。为了方便我们使用,Android SDK 提供有同步异步两种方式供开发者生成 Palette 对象:

// 同步方式:必须运行在子线程中
 Palette p = Palette.from(bitmap).generate();

 // 异步方式:可以在 UI 线程中执行
 Palette.from(bitmap).generate(new PaletteAsyncListener() {
     public void onGenerated(Palette p) {
         
     }
 });

Palette API 能够按照我们指定数量的颜色种类提取图片中的颜色,默认是 16 种颜色,可以通过 Palette.Builder API 设置。当然,提取颜色数量越多,耗时越久。考虑到实用性,系统默认提取有如下六种色调的颜色:

  • Vibrant
  • Vibrant Dark
  • Vibrant Light
  • Muted
  • Muted Dark
  • Muted Light

这些颜色都有相应的 getter 方法获取。这里要提到一个 Swatch (样品)类。对 Palette 对象所有颜色相关的操作都可以通过 Swatch 类间接获取。像上面这六种色调,都能通过对应的 Swatch 对象获取到。比如,获取图片主题色,可以直接从 palette 对象中获取:

int color = palette.getDominantColor(ContextCompat.getColor(mContext, R.color.blue));

也可以通过 swatch 对象间接获取:

int color = palette.getDominantSwatch().getRgb();

差别在于,Swatch 对颜色的相关信息做了一个封装处理。通过 Swatch 对象,我们可以获取颜色的 RGB、HSL 等值,和当前颜色在图片中的占比。更重要的一点是,能够获取适合显示在当前颜色背景中的内容色,比如文本标题颜色等。不得不说,Google 想的真周到,并且在源码设计上也是非常独到。

使用案例:色彩自适应的 Toolbar


前面说过,Palette 的用法可以有很多,就看你怎么用。这里就来举个非常炫酷的例子。

从图片列表页进入详情页,很常见的设计。在详情页,根据不同图片内容,提取主题色调,动态改变 Toolbar 背景色和内容色。这是静态图展示:

Android调色板获取不到bitmap的颜色 安卓调色板_API_02


看下本文相关的内容,使用 Palette API 提取图片颜色的的操作代码:

Palette.from(BitmapFactory.decodeResource(getResources(), res))
        .generate(new Palette.PaletteAsyncListener() {
            @Override
            public void onGenerated(Palette palette) {
                int color = palette.getDominantColor(ContextCompat.getColor(mContext, R.color.blue));
                int colorDark = palette.getDarkMutedColor(color);
                int titleTextColor = palette.getDominantSwatch().getTitleTextColor();
                mToolbarCtl.setContentScrimColor(color);
                mToolbarCtl.setStatusBarScrimColor(colorDark);
                mToolbarCtl.setCollapsedTitleTextColor(titleTextColor);
                mToolbarCtl.setExpandedTitleColor(titleTextColor);
                ToolbarColorizeHelper.colorizeToolbar(mToolbarTb, titleTextColor, PaletteDetailActivity.this);
            }
        });

ToolbarColorizeHelper 是一个辅助类,用于动态修改 Toolbar 除背景色之外的相关内容颜色,比如 Back Icon,Title 文本,Menu Item Icon 之类的。来源自GitHubGist,博客介绍自 这里。

最终实现的 Git 效果图就是这样:

Android调色板获取不到bitmap的颜色 安卓调色板_API_03