版权声明:

本账号发布文章均来自公众号,承香墨影(cxmyDev),版权归承香墨影所有。

每周会统一更新到这里,如果喜欢,可关注公众号获取最新文章。

未经允许,不得转载。

一、前言

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

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

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

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

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 的源码,对色彩的运算,也有了更加深入的了解。

使用 Palette 让你的 UI 色彩与内容更贴合的更多相关文章

  1. UI測试内容

    我们在实际工作其中,针对web应用程序,也就是常常所说的B/S系统,能够从例如以下方面来进行用户界面測试: 导航測试 导航描写叙述了用户在一个页面内操作的方式,在不同的用户接口控制之间,比如butto ...

  2. 十一、VueJs 填坑日记之使用Amaze ui调整列表和内容页面

    上一篇博文我们整合了Amaze ui,并且调整了一个头部header和底部footer文件,其实做起来也很简单,只要按照步骤来做,完全没有问题.今天我们来重新调整一下列表页面和内容页面,使我们做的后台 ...

  3. UI事件与内容,舞台与演员

    UI事件:创建/清除/显示/隐藏/填充内容/位置变化/形态变化/尺寸变化/颜色变化/ 非UI事件:点击/输入/拖动/

  4. element ui表格相同内容自动合并

    一开始觉得合并单元格很困难,什么鬼,后来仔细查看api,发现是可以实现的,特此记录下,直接看代码, 项目需求是第一列和第二列还有第16列需要相同内容进行合并,所以判断条件是不同的: 实现后效果如下: ...

  5. 浅谈UI设计中妙用无穷的深色系背景

    英文:medium 译者:优设网 - 陈子木 链接:http://www.uisdc.com/ui-benefits-of-dark-background# --------------------- ...

  6. Android Material Design之Toolbar与Palette

    转:http://blog.csdn.net/jdsjlzx/article/details/41441083 前言 我们都知道Marterial Design是Google推出的全新UI设计规范,如 ...

  7. 优质UI的7条准则(一)

    本文原文来自于 Medium:https://medium.com/@erikdkennedy/7-rules-for-creating-gorgeous-ui-part-1-559d4e805cda ...

  8. android 5.0 -- Palette

    Palette用来从图片资源中获取颜色内容. 下面是个对颜色值使用的工具类: public class PaletteUtils { public static int getColorWithDef ...

  9. Palette状态栏颜色提取,写的不错就分享了

    Palette 说Palette之前先说下前面提到的Pager.ViewPager是什么大家应该都是知道的了,一般ViewPager.xxxTabStrip.Fragment三个好基友是一起出现的.这 ...

随机推荐

  1. unable to create …

    问题描述: 在新建Android Application时会出现unable to create the selected property page 解决方法: 将用户PATH路径中的jdk路径放到 ...

  2. POJ3660 Cow Contest floyd传递闭包

    Description N (1 ≤ N ≤ 100) cows, conveniently numbered 1..N, are participating in a programming con ...

  3. echarts 支持svg格式

    今天研究了下echarts的svg格式.发现用ai生成svg格式的图片,echarts上面显示不了. 经过了多次的百度和谷歌终于找到了用Method Draw画出来的svg格式,echarts就能加载 ...

  4. 福利 c++ 标准头文件大全

    #include<cmath> #include<math.h> #include<ctype.h> #include<algorithm> #incl ...

  5. NYOJ--353--bfs+优先队列--3D dungeon

    /* Name: NYOJ--3533D dungeon Author: shen_渊 Date: 15/04/17 15:10 Description: bfs()+优先队列,队列也能做,需要开一个 ...

  6. ASP.NET windows验证IIS配置

    Windows验证时,需要配置IIS,把匿名验证设为disable,windows验证设为enable,window7 默认为匿名验证为enable,windows验证为disable. 否则会sys ...

  7. 开源社群系统ThinkSNS+安装部署演示视频!

    社群系统TS+一期版本发布之后,很多小伙伴们反馈安装部署有些困难,那么今天由我们的颜值与技术实力担当乔斌大佬通过录制视频的形式,给大家演示一下部署的整个过程,录制过程中有些杂音,请各位尽情谅解,后续我 ...

  8. ThinkSNS+ alpha.2 版本发布,功能抢先看!【社交系统研发日记六】

    今天的研发日记,我们不讲技术,我们来看看,社交系统TS+从今天开始全面内测开始,都发布了什么功能. 其实,alpha.1 早上打的 tag ,晚上因为增加了两个核心功能,所以又打了 alpha.2 t ...

  9. Oracle的安装问题

    1. 安装时提示:unable to create directory: /u01/oracle/oradata 这个是由于以oracle用户进行安装时,之前没有创建/u01/这个目录,要知道orac ...

  10. 详实的SQL学习笔记

    写在前面:最近在上海找工作,前前后后面试了N家单位,发现各个公司对程序员的数据库知识尤其是SQL语句的掌握程度有很高的要求,作为一名光荣的程序员,不会玩儿SQL语句走在街上根本不好意思和人打招呼!好了 ...