Fork me on GitHub

 

 

使用Palette API选择颜色

 

良好的视觉设计是app成功所必不可少的, 而色彩设计体系是设计的基础构成. Palette包是支持包, 能够从图片中解析出突出的颜色, 从而帮助你创建出视觉迷人的应用

你能够使用Palette包设计布局主题, 并把自定义色彩应用到可视化元素中. 比如, 你可以根据专辑封面, 用Palette创建为歌曲创建一个彩色标题卡片, 或者当应用背景图片发生改变时调整toolbar颜色. Palette对象给予你权限访问Bitmap图片里面的颜色, 同时也根据Bitmap提供了6个主要的颜色, 供你填写设计选择.

 

设置依赖

 

Palette为库从版本Android Support Library 24.0.0引入, 可以在build.gradle中按照如下代码添加Palette依赖:

1 android {
2   compileSdkVersion 27
3   ...
4 }
5 
6 dependencies {
7   ...
8   implementation 'com.android.support:palette-v7:27.1.1'
9 }

 

创建Palette对象

 

Palette给予你权限访问图片中的基本颜色, 以及重叠文本对应的颜色. 可以根据给定资源图片, 使用palette设计应用风格, 动态改变应用的色彩体系.

要创建Palette, 首先在从Bitmap中实例化Palette.Builder. 然后在生成Palette之前, 可以使用Palette.Builder来自定义Palette.

 

生成Palette实例

 

首先, 利用Palette的from(Bitmap)方法从Bitmap中生成Palette.Builder. 之后利用这个Builder同步或者异步地生成Palette. 如果你想在generate()方法被调用的线程中创建Palette对象, 使用同步的palette生成. 如果你想在不同的线程上异步地生成Palette, 就要使用Palette.PaletteAsyncListener.onGenerated方法在Palette生成之后立即访问它.
下面的代码片断展示了两种不同的Palette生成方式:

 1 // Generate palette synchronously and return it
 2 public Palette createPaletteSync(Bitmap bitmap) {
 3   Palette p = Palette.from(bitmap).generate();
 4   return p;
 5 }
 6 
 7 // Generate palette asynchronously and use it on a different
 8 // thread using onGenerated()
 9 public void createPaletteAsync(Bitmap bitmap) {
10   Palette.from(bitmap).generate(new PaletteAsyncListener() {
11     public void onGenerated(Palette p) {
12       // Use generated instance
13     }
14   });
15 }


如果你需要持续为多个有序图片生成多个Palette, 考虑将Palette实例缓存起来, 以避免减缓UI性能. 你也不应该在主线程中创建Palette.

 

自定义Palette

 

Palette.Builder允许你自定义Palette, 通过从结果Palette中选择多少种颜色, Builder使用图片的什么区域生成Palette, Palette中允许什么颜色等. 比如, 你能够过滤掉黑色, 或者, Builder只能够使用图片的上半部分生成Palette.

通过Palette.Builder中的下列方法, 可以微调Palette尺寸和颜色:

  • addFilter(): 该方法添加了过滤器, 用以表明结果Palette中什么颜色是允许的. 传入自己的Palette.Filter, 修改isAllowed()方法来决定Palette过滤哪些方法.
  • maximumColorCount(): 该方法设置了Palette中最大的颜色数目. 默认值是16, 最优值依赖于源图. 对于风景图, 最优值处于8~16, 而肖像图通常拥有16~24个值. 颜色越多, Palette.Builder生成Palette就需要花费超久的时间.
  • setRegion(): 该方法指出了生成Palette时, Builder使用Bitmap的什么区域. 你只能使用这个方法从Bitmap中生成Palette, 而不会影响源图.
  • addTarget(): 该方法允许你通过向Builder添加Target色彩配置文件来执行自己的颜色匹配. 如果默认的Target并不有效的话, 高级开发人员能够使用Target.Builder创建自己的Target.

 

提取色彩配置文件

 

基于材料设计标准, Palette库从图片中提供常用的色彩配置文件. 每一个文件被一个Target定义, 从Bitmap图片中提取的色彩基于饱和度, 亮度和分布(Bitmap中表示色彩的像素数)对文件进行评分. 对于每一个文件, 具有最好分数的颜色定义了给定图片的色彩配置文件.

默认情况下, 对于给定图片, Palette对象包含16个基本颜色. 在生成Palette的时候, 你可以通过Palette.Builder自定义颜色数. 提取更多的色彩对于每个色彩配置文件提供了更多的潜在匹配, 但也引起Palette.Builder花费更久的时间来生成Palette.

Palette库尝试提取以下6个色彩配置文件:

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

每一个Palette.get<Profile>Color()方法返回了Palette中的颜色, 而每一个Palette关联了一个特定的配置文件, 其中, <Profile>被以上6个色彩配置文件名取代. 比如, 获取Dark Vibrant色彩配置文件的方法是getDarkVibrantProfile(). 因为不是所有的图片都会包含所有的色彩配置文件, 所以, 你必须也提供一个默认颜色返回.

 

使用样本创建色彩体系

 

Palette对象也为每一个色彩配置文件生成 Palette.Swatch对象. Palette.Swatch对象包含对象的配置文件关联的颜色和颜色的像素分布.

Swatch拥有额外的方法来访问色彩配置文件更多的信息, 比如HSL值, 像素分布等. 你能够通过使用getBodyTextColor()和getTitleTextColor()来生成更多繁杂的色彩体系和应用主题. 这些方法返回的颜色恰好配合Swatch的颜色使用.

每一个Palette.get<Profile>Swatch()方法返回了关联特定配置文件的Swatch. 尽管get<Profile>Swatch()方法并不默认值参数, 如果图片中并不存在特定的某个配置文件, 该方法会返回null. 由此, 你应该在使用Swatch之前判断它是否为空. 比如, 下面的代码从Palette中获取了标题文本颜色, 并检查了Vibrant Swatch是否为空:

1 Palette.Swatch vibrant = myPalette.getVibrantSwatch();
2 if(vibrant != null){
3     int titleColor = vibrant.getTitleTextColor();
4     // ...
5 }


要访问Palette中的所有颜色, getSwatches()方法返回了包含图片中生成的所有Swatch的列表, 包括标准的6个色彩配置文件.

下面的代码片断使用了上述代码片断, 同步生成了Palette, 获取了Vibrant Swatch, 改变了Toolbar颜色, 以匹配Bitmap图片. 下面的图片则展示了结果和toolbar.

 

 1 // Set the background and text colors of a toolbar given a
 2 // bitmap image to match
 3 public void setToolbarColor(Bitmap bitmap) {
 4     // Generate the palette and get the vibrant swatch
 5     // See the createPaletteSync() method
 6     // from the code snippet above
 7     Palette p = createPaletteSync(bitmap);
 8     Palette.Swatch vibrantSwatch = p.getVibrantSwatch();
 9 
10     Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
11 
12     // Load default colors
13     int backgroundColor = ContextCompat.getColor(getContext(),
14         R.color.default_title_background);
15     int textColor = ContextCompat.getColor(getContext(),
16         R.color.default_title_color);
17 
18     // Check that the Vibrant swatch is available
19     if(vibrantSwatch != null){
20         backgroundColor = vibrantSwatch.getRgb();
21         textColor = vibrantSwatch.getTitleTextColor();
22     }
23 
24     // Set the toolbar background and text colors
25     toolbar.setBackgroundColor(backgroundColor);
26         toolbar.setTitleTextColor(textColor);
27 }

 

posted on 2018-07-05 16:18  SilentKnight  阅读(4512)  评论(0编辑  收藏  举报