使用 Palette 让你的 UI 色彩与内容更贴合
版权声明:
本账号发布文章均来自公众号,承香墨影(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 使用起来非常的简单,既然目的是从一个图片中提取颜色,它的步骤就有:
- 传递一个 Bitmap,得到一个 Palette。
- 通过 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() 中,主线逻辑:
首先会通过
scaleBitmapDown()方法,将图片压缩成一个小像素的,等于生成了一个新的 Bitmap 对象,这样有利于内存的管理,并且也减少了计算量。然后再通过 mRegion 判断是否只是提取图片的某个区域,默认是完整的图片全部提取,当然也可以对 mRegion 进行配置。
之后再构造一个 ColorCutQuantizer 对象,使用它的
getQuantizedColors()方法得到 Swatch。使用完前面压缩的 Bitmap 对象之后,再使用 recycle() 将其回收掉。
最后,通过 Palette 本身的构造函数,去生成一个 Palette 对象,返回出去。
接下来看看比较关键的 ColorCutQuantizer 中的实现逻辑。
从代码中可以看到,其中的逻辑还是很清晰的。
- 首先通过
quantizeFromRgb888()方法,将每个像素的颜色进行量化,类似于将每个颜色取一个靠近的设置。举个不恰当的例子,将不同深度的红,都标记成红色。 - 再通过
shouldIgnoreColor() 过滤掉不需要的颜色。 - 最终获取到的颜色,如果小于等于我们设置的 maxColors,就可以通过
approximateToRgb888()生成一批 Swatch。 - 如果大于 maxColors,就再通过
quantizePixels()去掉一些杂色。 - 无论如何,最终操作的就是这里得到的 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 色彩与内容更贴合的更多相关文章
- UI測试内容
我们在实际工作其中,针对web应用程序,也就是常常所说的B/S系统,能够从例如以下方面来进行用户界面測试: 导航測试 导航描写叙述了用户在一个页面内操作的方式,在不同的用户接口控制之间,比如butto ...
- 十一、VueJs 填坑日记之使用Amaze ui调整列表和内容页面
上一篇博文我们整合了Amaze ui,并且调整了一个头部header和底部footer文件,其实做起来也很简单,只要按照步骤来做,完全没有问题.今天我们来重新调整一下列表页面和内容页面,使我们做的后台 ...
- UI事件与内容,舞台与演员
UI事件:创建/清除/显示/隐藏/填充内容/位置变化/形态变化/尺寸变化/颜色变化/ 非UI事件:点击/输入/拖动/
- element ui表格相同内容自动合并
一开始觉得合并单元格很困难,什么鬼,后来仔细查看api,发现是可以实现的,特此记录下,直接看代码, 项目需求是第一列和第二列还有第16列需要相同内容进行合并,所以判断条件是不同的: 实现后效果如下: ...
- 浅谈UI设计中妙用无穷的深色系背景
英文:medium 译者:优设网 - 陈子木 链接:http://www.uisdc.com/ui-benefits-of-dark-background# --------------------- ...
- Android Material Design之Toolbar与Palette
转:http://blog.csdn.net/jdsjlzx/article/details/41441083 前言 我们都知道Marterial Design是Google推出的全新UI设计规范,如 ...
- 优质UI的7条准则(一)
本文原文来自于 Medium:https://medium.com/@erikdkennedy/7-rules-for-creating-gorgeous-ui-part-1-559d4e805cda ...
- android 5.0 -- Palette
Palette用来从图片资源中获取颜色内容. 下面是个对颜色值使用的工具类: public class PaletteUtils { public static int getColorWithDef ...
- Palette状态栏颜色提取,写的不错就分享了
Palette 说Palette之前先说下前面提到的Pager.ViewPager是什么大家应该都是知道的了,一般ViewPager.xxxTabStrip.Fragment三个好基友是一起出现的.这 ...
随机推荐
- nopcommerce 开源商城
http://www.nopchina.net/ 中文网 http://www.nopcommerce.com/downloads.aspx 源码下载 如果要在数据库中添加一个新的数据表,需要按 ...
- Head First 设计模式 第3章 装饰者模式
第3章 装饰者模式 1.定义/说明 动态.透明的将职责附加到对象上(或从对象上撤销),而不影响其他对象.若要扩展功能,装饰者模式提供了比继承更富有弹性的替代方案. 2.介绍 首先让我们先来介绍一下场景 ...
- 身在魔都的她,该不该继续"坚持"前端开发?
一 这个女孩儿,是我很好很好很好的一位朋友,也是中学的同学,去年从她的本科大学毕业,毕业后由于没找到合适的工作而选择去培训机构培训了比较火爆的前端开发,之后去了上海找工作,但是由于一些原因在从上一家公 ...
- python进阶(7):面向对象进阶
学了面向对象三大特性继承,多态,封装.今天我们看看面向对象的一些进阶内容,反射和一些类的内置函数. 一.isinstance和issubclass class Foo: pass class Son( ...
- 浅谈分析表格布局与Div+CSS布局的区别
(1)表格布局 表格布局容易掌握,布局方便.但表格布局需要通过表格的间距或者使用透明的gif图片来填充布局板块间的间距,这样布局的网页中表格会生成大量难以阅读和维护的代码:而且表格布局的网页要等整个表 ...
- java 数组的冒泡排序
冒泡排序 (1)冒泡排序算法的运作如下:(从后往前) 比较相邻的元素.如果第一个比第二个大,就交换他们两个. 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对.在这一点,最后的元素应该会是最 ...
- 设计模式之建造者模式Builder(创建型)
1. 概述 在软件开发的过程中,当遇到一个“复杂的对象”的创建工作,该对象由一定各个部分的子对象用一定的算法构成,由于需求的变化,复杂对象的各个部分经常面临剧烈的变化,但将它们组合在一起的算法相对稳定 ...
- 第一天的php体验
第一次了解php.以前对于程序猿的认知是很片面的.因为没有了解过.今天通过一天的了解交流,有了新的认知.对于这个主要应用于前端的语言还是很有兴趣的.毕竟可以亲眼看到自己做出来的网页,心里的成就感肯定满 ...
- 安卓APP测试容易忽略的地方
我们手机APP测试,主要针对的是android和ios两大主流操作系统,总体上来说android手机型号.版本多,bug也多:ios相对bug少.下面就针对Android说一下最容易忽略的测试点吧. ...
- 分页(将数据库中的多条数据一页一页的显示在jsp页面中)
一.显示数据库中的多条数据为什么要用分页 在真正的开发中,数据库中所存储的数据绝对不像我们平时所写的那样,仅仅有几条数据,而是有几十条甚至上百条,像淘宝京东的用户把都是上几十万甚至百万的.如果这时候在 ...