使用Palette类提取图片的颜色信息

本文介绍如何使用 Android Support Library v21 中的 Palette 类来从图片中提取颜色信息,并展示了如何根据不同类型的图片调整调色板大小,以及如何使用生成的调色板来改变界面元素的颜色。

原文:http://qichaochen.github.io/2014/11/16/105-Android-5.0-Palette-01/ 

在Material Design设计中很重要的一部分内容是应用中图片颜色和文字颜色需要和主题相匹配,比如下面在这个应用:

文本的颜色根据不同图片动态进行对应适配(也许你会说,如果全部用白色文本多省事,何必这么麻烦呢?额…可以脑补一下高富帅和矮矬穷的区别)

那么在应用程序中如何提取图片的颜色信息呢?可以提取多少种颜色信息呢? 在最新的Support Library v21提供了Palette类可以很方便的实现这个需求。

下面看一下提取图片颜色信息的步骤和注意事项:

1.首先需要添加Palette的依赖

在build.gralde的dependencies添加appcomat v7和palette-v7依赖

1
2
3
4
5
dependencies {
     //...其他依赖
     compile  'com.android.support:appcompat-v7:21.0.0'
     compile  'com.android.support:palette-v7:21.+'
}

添加完成后需要同步一下Gradle,同步成功后就可以使用Palette类了。

2.创建Palette对象

官方提供了四种根据Bitmap对象来创建Palette对象的方法,具体分别如下:

两种同步方法:

1
2
3
4
5
// 最好在加载图片线程中使用
// 默认调色板大小(16).
Palette p = Palette.generate(bitmap);
//设置调色板大小(24)
Palette p = Palette.generate(bitmap, 24);

两种异步方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 简单快速的实现方法,内部使用AsyncTask
// 但是可能不是最优的方法(因为有线程的切换)
// 默认调色板大小(16).
Palette.generateAsync(bitmap,  new  Palette.PaletteAsyncListener() {
     @Override
     public void onGenerated(Palette palette) {
         // palette为生成的调色板
     }
});
// 设置调色板大小(24)
Palette.generateAsync(bitmap, 24,  new  Palette.PaletteAsyncListener() {
     @Override
     public void onGenerated(Palette palette) {
         // palette为生成的调色板
     }
});

调色板的大小值越大,生成的调色板的时间越长,数值越小,得到的颜色信息也越少,调色板的大小最好根据图片类型来决定,比如:

  • 联系人头像:最优值24~32

  • 风景图:8-16

当然默认是16,大多数情况下都可以取得很好的效果。

3.使用Palette对象

生成了Palette对象后就可以尝试获取六种不同的色板,具体如下:

1
2
3
4
5
6
1. Palette.Swatch s1 = Palette.getVibrantSwatch();  //充满活力的色板
2. Palette.Swatch s2 = Palette.getDarkVibrantSwatch();  //充满活力的暗色类型色板
3. Palette.Swatch s3 = Palette.getLightVibrantSwatch();  //充满活力的亮色类型色板
4. Palette.Swatch s4 = Palette.getMutedSwatch();  //黯淡的色板
5. Palette.Swatch s5 = Palette.getDarkMutedSwatch();  //黯淡的暗色类型色板(翻译过来没有原汁原味的赶脚啊!)
6. Palette.Swatch s6 = Palette.getLightMutedSwatch();  //黯淡的亮色类型色板

可以根据需求自由选择色板类型(充满活力和或充满活力暗色类型色板应该是大部分开发经常使用的),有了色板就可以根据色板来获取具体颜色信息,在Swatch色板中提供了五种颜色信息,分别如下:

1
2
3
4
5
1. getPopulation(): the number of pixels represented by  this  swatch
2. getRgb(): the RGB value of  this  color.
3. getHsl(): the HSL value of  this  color.
4. getBodyTextColor(): the RGB value of a text color which can be displayed on top of  this  color.
5. getTitleTextColor(): the RGB value of a text color which can be displayed on top of  this  color.

示例代码如下:

1
2
3
4
5
Palette.Swatch swatch = palette.getVibrantSwatch();
TextView titleView = ...;
if  (swatch !=  null ) {
     titleView.setBackgroundColor(swatch.getRgb());
     titleView.setTextColor(swatch.getTitleTextColor());  //设置文本颜色

请注意必须对swatch进行是否为null判断,因为如果面板无法找到相匹配的标准色,那么然后将返回null,不进行判断将会出现空指针异常。

最后附上三个测试效果图和完整代码。



完整代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
package io.github.qichaochen.android50;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.graphics.Palette;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ImageView;
public class MainActivity extends ActionBarActivity {
     private ImageView image, iv1, iv2, iv3, iv4, iv5, iv6;
     private Palette palette;
     private Palette.Swatch s1,s2,s3,s4,s5,s6;
     private int index = 0;
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super .onCreate(savedInstanceState);
         setContentView(R.layout.activity_main);
         iv1 = (ImageView) findViewById(R.id.iv1);
         iv2 = (ImageView) findViewById(R.id.iv2);
         iv3 = (ImageView) findViewById(R.id.iv3);
         iv4 = (ImageView) findViewById(R.id.iv4);
         iv5 = (ImageView) findViewById(R.id.iv5);
         iv6 = (ImageView) findViewById(R.id.iv6);
         image = (ImageView) findViewById(R.id.image);
         GetPalette(R.drawable.a11);
     }
     private void GetPalette(int imageId) {
         image.setImageResource(imageId);
         //使用默认的调色板大小(16)
         Palette.generateAsync(BitmapFactory.decodeResource(getResources(), imageId),  new  Palette.PaletteAsyncListener() {
             @Override
             public void onGenerated(Palette palette) {
                 s1 = palette.getVibrantSwatch();
                 s2 = palette.getDarkVibrantSwatch();
                 s3 = palette.getLightVibrantSwatch();
                 s4 = palette.getMutedSwatch();
                 s5 = palette.getDarkMutedSwatch();
                 s6 = palette.getLightMutedSwatch();
                 if  (s1 !=  null ) {
                     iv1.setBackgroundColor(s1.getRgb());
                     s1.getPopulation();
                 }
                 if  (s2 !=  null ) {
                     iv2.setBackgroundColor(s2.getRgb());
                 }
                 if  (s3 !=  null ) {
                     iv3.setBackgroundColor(s3.getRgb());
                 }
                 if  (s4 !=  null ) {
                     iv4.setBackgroundColor(s4.getRgb());
                 }
                 if  (s5 !=  null ) {
                     iv5.setBackgroundColor(s5.getRgb());
                 }
                 if  (s6 !=  null ) {
                     iv6.setBackgroundColor(s6.getRgb());
                 }
             }
         });
     }
     @Override
     public boolean onCreateOptionsMenu(Menu menu) {
         getMenuInflater().inflate(R.menu.menu_main,menu);
         return  true ;
     }
     @Override
     public boolean onOptionsItemSelected(MenuItem item) {
         if  (item.getItemId() == R.id.action_settings){
             index++;
             if  (index%3 == 0){
                 GetPalette(R.drawable.a11);
             else  if  (index % 3 == 1){
                 GetPalette(R.drawable.a12);
             else  if  (index % 3 == 2){
                 GetPalette(R.drawable.a13);
             }
         }
         return  true ;
     }
}

参考:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值