使用 Palette 使你的 UI 色彩与内容更贴合

开发 开发工具
今天介绍一个 Android 下比较有意思的 Support v7 库,Palette,它翻译过来就是调色板。

[[202255]]

一、前言

今天介绍一个 Android 下比较有意思的 Support v7 库,Palette,它翻译过来就是调色板。

Palette 可以从一张 Bitmap 中提取出它突出的颜色,这样我们就可以将提取出来的颜色设置在 App 的固定 UI 中(例如:ToolBar 的背景),使得 UI 页面的整体风格更加的美观和融洽。

比如,对于一些影视类的 App,视频详情页的主题都是视频的海报,那么对于页面背景,我们可以提取视频海报的颜色,设置在背景上,使得效果更佳柔和美观。

Palette 是一个 Support v7 的包,如果使用 Gradle 引入依赖,这里使用***的 26.+。

  1. compile "com.android.support:palette-v7:26.+" 

二、Palette 的使用

Palette 使用起来非常的简单,既然目的是从一个图片中提取颜色,它的步骤就有:

  1. 传递一个 Bitmap,得到一个 Palette。
  2. 通过 Palette 提取需要的颜色。

就是这么简单,如同要将大象放冰箱,需要几步一样清晰。

那么接下来我们先来了解它使用的细节。

2.1 传递 Bitmap 得到一个 Palette

Palette 在旧版本上有一些 generate() 的方法,用于生成一个 Palette 对象,但是在新版本上已经被标记为 @Depercated 了,所以这里不推荐使用。

而在新版上,推荐使用 Palette.Builder 来创建我们的 Palette 对象,我们可以通过 from() 方法使用它。

一般我们使用***个方法即可,直接传递进去一个 Bitmap 对象。得到 Builder 之后,我们还可以配置一些规则,但是一般我们不需要进行额外的(后面会讲到)。再通过 Builder.generate() 即可得到我们需要的 Palette 对象了。

2.2 通过 Palette 提取颜色

Palette 从图片中提取的颜色,有很多选择。这里又涉及到另外一个类,Swatch 。

Palette 可被提取的每个颜色,都被封装成一个 Swatch 对象,用来管理多种颜色。

这些 Swatch 有:

  • DominantSwatch
  • VibrantSwatch
  • DarkVibrantSwatch
  • LightVibrantSwatch
  • MutedSwatch
  • DarkMutedSwatch
  • LightMutedSwatch

其实这些 Swatch,真的不太好解释其意义,唯一特别一点的就是 DominantSwatch ,它是从图片中提取的最突出的颜色。

这些 Swatch 在 Palette 都提供了对应的 getXxx() 方法获得。不过需要注意的是,这些 getXxx() 方法可能会得到一个 null ,因为有些颜色是没有的。

如果只是需要得到一个颜色值,Palette 同时也提供了对应的 getXxxColor() 方法,方便我们使用。

得到 Swatch 对象之后,就可以通过对应的 Swatch 中对应的 Api 获取我们需要的颜色值。

  • getPopulation() :Swatch 中的像素个数。
  • getRgb():颜色的 RGB 值。
  • getHsl():颜色的 HSL 值。
  • getBodyTextColor():对应的文字颜色值。
  • getTitleTextColor():对应的标题文字颜色值。

通常来说,我们只需要通过 getRgb() 获取到对应的颜色设置在背景上,如果背景之上还有文字内容,可以通过 getBodyTextColor() 提取出与背景匹配的文字颜色值,这样可以显得更加的柔和,让文字看起来更清晰和舒服。比如,如果一个深色的背景,为它设置一个默认的深色文字,基本上就看不见了,因为对比对太弱。

2.3 举个例子

到这里,基本上 Palette 的基本 Api 就讲解清楚了,下面举个实际的例子来看看。

这里找了三张 Eason 的海报,用于做 Palette 的 Demo 资源,间隔去替换图片,然后分别提取出对应的颜色和字体颜色,设置在下面按钮的背景上,然后每 3s 切换一张图片。

因为有一些图片,获取的 Swatch 可能会返回 null ,所以这里用了一个比价扎眼的红色,作为错误色。

以下是获取 Swatch 的代码。

接下来通过 Swatch 提取我们需要的颜色。

这里分别获取了需要的颜色以及字体颜色,下面看看运行的效果:

 

可以看到,确实有一些颜色,被标记成了红色,说明当前图片有获取不到的对应颜色。

三、分析 Palette 的实现

3.1 Palette 的主线逻辑

继续深入看看 Palette 的实现原理,先从主线开始看。

从 Builder.generate() 开始。

从代码中可以看到,在 generate() 中,主线逻辑:

  1. 首先会通过 scaleBitmapDown() 方法,将图片压缩成一个小像素的,等于生成了一个新的 Bitmap 对象,这样有利于内存的管理,并且也减少了计算量。
  2. 然后再通过 mRegion 判断是否只是提取图片的某个区域,默认是完整的图片全部提取,当然也可以对 mRegion 进行配置。
  3. 之后再构造一个 ColorCutQuantizer 对象,使用它的 getQuantizedColors() 方法得到 Swatch。
  4. 使用完前面压缩的 Bitmap 对象之后,再使用 recycle() 将其回收掉。
  5. ***,通过 Palette 本身的构造函数,去生成一个 Palette 对象,返回出去。

接下来看看比较关键的 ColorCutQuantizer 中的实现逻辑。

从代码中可以看到,其中的逻辑还是很清晰的。

  1. 首先通过 quantizeFromRgb888() 方法,将每个像素的颜色进行量化,类似于将每个颜色取一个靠近的设置。举个不恰当的例子,将不同深度的红,都标记成红色。
  2. 再通过 shouldIgnoreColor() 过滤掉不需要的颜色。
  3. 最终获取到的颜色,如果小于等于我们设置的 maxColors,就可以通过approximateToRgb888() 生成一批 Swatch。
  4. 如果大于 maxColors,就再通过 quantizePixels() 去掉一些杂色。
  5. 无论如何,最终操作的就是这里得到的 mQuantizedColors 对象。

3.2 Swatch 的 Target

所有需要的 Swatch ,都是被 Target 对象所标记。不同的 Swatch 都是通过 Target 中标记的常量值,进行运算,得到行的颜色。

 

3.3 过滤掉不需要的颜色

Palette 可以设置一些我们不需要的颜色,让它们不参与运算。这里的过滤条件,通过 Filter 来设定,并且 Palette 也提供给了一个 DEFAULT_FALTER 来标记默认的过滤颜色。

 

可以看到,默认的 Filter 会过滤掉一些靠近黑和白的颜色。

当然,我们也可以自己定义 Filter ,并通过 Palette 中的 addFilter()、clearFilters() 来管理它。

这里存储 Filter 的是一个 ArrayList ,所以我们是可以定义很多个 Filter 加入进去的,它们都会生效。

3.4 设置 MaxColor

在 ColorCutQuantizer 中,被使用的 maxColor ,主要用于标记需要使用的颜色个数。它是可以通过 maximumColorCount() 方法,进行设置的,如果不对其进行设定,默认值为 16。

理论上来说,这里设置的maxColor 的值越大,运算花费的时间就越长。而越小,可以被选择的色值也就越少。

所以***的做法是根据当前 Bitmap 的用途来决定,色彩越丰富的图,设置的 maxColor 越大,即可。不过正常来说也不需要额外的设定,默认的配置就挺好用了。

四、小结

到这里就分析完 Palette 的所有相关的内容,不要仅仅满足使用。实际上看了 Palette 的源码,对色彩的运算,也有了更加深入的了解。

【本文为51CTO专栏作者“张旸”的原创稿件,转载请通过微信公众号联系作者获取授权】

戳这里,看该作者更多好文

责任编辑:武晓燕 来源: 51CTO专栏
相关推荐

2010-05-13 18:09:41

2021-06-29 15:52:03

PythonPOST

2016-01-28 13:33:07

2020-08-11 23:25:53

边缘计算物联网数据

2009-11-03 09:06:14

数据备份数据安全网络安全

2011-04-02 11:46:50

UI嵌入式开发

2013-01-06 09:26:06

Wi-Fi网络协议

2020-02-11 12:35:19

Kubernetes容器

2017-11-14 08:27:32

云中数据存储

2018-02-25 12:19:02

2019-09-23 10:59:31

机器学习算法编程

2019-09-23 11:17:46

机器学习数据技术

2021-12-29 16:34:19

JavaScript代码库开发

2017-02-24 11:31:17

Android颜色提取Palette

2018-05-14 09:35:54

AI 供应链管理

2024-04-11 11:37:25

人工智能机器学习自动化流程

2019-08-05 09:39:05

2021-06-07 17:10:07

区块链出入口控制物联网

2018-10-08 14:16:38

2012-12-10 11:24:53

点赞
收藏

51CTO技术栈公众号