版权声明:

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

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

未经允许,不得转载。

一、前言

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

使用 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. web组件工具之获取表单数据:webUtils

    本文需要的架包:commons-beanutils-1.8.3.jar.commons-logging-1.1.3.jar.servlet-api.jar. 本文共分为五部分:1)封装通用工具类:从表 ...

  2. OVS故障处理一例

    OVS下无法访问内部网站 遇到朋友求助的一个客户问题,环境是这样的,客户在自己的iaas平台(不是openstack)上使用ovs,物理交换机上配置vlan和dhcp service,计算节点的ovs ...

  3. 聊聊synchronized的锁问题

    本文不会特别深入细致地讨论synchronized,只是做一个通俗易懂的说明,以及看清一类问题的本质,希望能给大家一点启发. 问题描述 有一个类A,提供了三个方法.分别是静态同步方法,非静态同步方法, ...

  4. ORACLE - 系统参数调整

    一.内存调整 oracle 11g中,ORACLE把SGA与PGA统一管理,总和为memory_target参数的设定,也就是MAX(SGA+PGA)<= memory_target(当然可以在 ...

  5. WAS 部署 Birt 报表出现 error.CannotStartupOSGIPlatform 和 更新web.xml

    在WAS7.0中部署Birt报表会出现error.CannotStartupOSGIPlatform错误,通常需要这样修改 1.依次打开Applications->WebSphere enter ...

  6. Java中的24种设计模式与7大原则 (转)

    一.创建型模式 1.抽象工厂模式(Abstract factory pattern): 提供一个接口, 用于创建相关或依赖对象的家族, 而不需要指定具体类.2.生成器模式(Builder patter ...

  7. div标签清除float浮动样式方法

    方法一. 这个方法来源于positioniseverything ,通过after伪类实现,完全兼容当前主流浏览器. 1 <style type="text/css"> ...

  8. Linux入门基础知识

    注:内容系兄弟连Linux教程(百度传课:史上最牛的Linux视频教程)的学习笔记. Linux入门基础知识 1. Unix和Linux发展历史 二者就像父子关系,当然Unix是老爹.1965年,MI ...

  9. java亦或(^)

    在java程序里面的异或用法: 相同输出0,不同输出1,例如: System.out.println(1^1); 输出0 System.out.println(1^2):输出3,因为最后2个低位都不一 ...

  10. java多线程系列(七)---Callable、Future和FutureTask

    Callable.Future和FutureTask 前言:如有不正确的地方,还望指正. 目录 认识cpu.核心与线程 java多线程系列(一)之java多线程技能 java多线程系列(二)之对象变量 ...