关于Android配色 自适应颜色的实现

在Android4.4系统中,更加详细地介绍了关于颜色的细节并提供了使用colour的新教程,以使我们的应用更加独一无二。也就是说,作为一个设计师或者开发者,为你的APP做完美的配色已经变成了你的职责。

可以通过改变Android Framework界面元素的默认蓝色来使应用更加独特。 ——来自Android Design

最简单的方式就是给Action Bar加上一层自定义的背景,但是在我现在写的一个APP中我希望可以更灵活一些(做到自适应),自适应颜色的最好例子就是iTunes了,它会从专辑中获取配色方案,作用于弹出的曲目列表。

color-matching-itunes

所以,我准备在Android上实现这个技术。

基本理论知识

在网上搜索一遍后,我发现了很多开源的实现方式,不过是用其他语言写的。最好的版本是一个JavaScript库,叫Color Thief,我从里面学到了很多实现这个技术需要的知识,正好是我需要的。

图像量化

这里要做的第一步就是量化源图像,通俗地说,就是减少图像上使用的颜色种类。如果你喜欢动态的GIF,那么只能用8位的色板,所以每一帧最多可以使用256种颜色。

为此,我们就需要减少颜色使用,只使用一些主要的颜色,那我们就用默认的色板吧,再根据需要弄出一些其他的颜色。稍后将详细介绍。

现在需要选择量化算法了,Color Thief用了一个修改版的MCQ(Median Cut Quantization)算法,另称作MMCQ(Modified Median Cut Quantization),如果想了解更多关于MMCQ的信息,可以来 这里 。其他的比较著名的量化技术还有NeuQuantOctTree

我还在《Principles of Digital Image Processing 》这本书上找到了一个JAVA的MCQ实现,托管在GitHub上。

这个MCQ算法有很多很棒的特性,所以我决定就用它了:

  • 它很快。它比NeuQuant和OctTree还快,在移动设备上这点尤其重要;
  • 它内部使用了统计直方图,每种色块都绑定了一个数值,之后排序的时候更方便。

虽然MCQ算法生成的图像质量不是最好的,但是这里只是需要它生成的调色板,不用展示生成的图像,所以,还不错。

处理结果

以下就是处理后的结果,使用Color Thief的例子里的图像。之前说过MCQ里面带有统计直方图,所以我们可以排列出每种颜色使用的频率,它显示了调色板排序后的列表。当然,这还是可以继续改进。

color-matching-result-1

color-matching-result-2

color-matching-result-3

这些结果和Color Thief生成的图像有点不一样:

  • 我的版本选择蓝色作为主要的颜色;
  • Color Thief挑选了蓝色,银色和绿色作为主要颜色;
  • Color Thief没有选到那些灰色的阴影。所以还需要改进。

接着上文讲的,可以调用MedianCutQuantizer对象的getQuantizedColors()这个方法可以获取调色板。我们可以以颜色使用的数量和比重来对这个集合进行降序显示。很不幸的是结果表明大多数图像用的颜色是黑色和白色(或相近的颜色),这颜色根本不能让我们的应用显得更独特,所以我们要考虑到底选择什么颜色了。

对于我自己的应用来说,我准备使用以下的调色方案:

  • 第一位的主色是一种鲜艳的颜色;
  • 第二位主色是区别一于第一位主色的另一种亮色;
  • 第三位主色是和第一位和第二位主色对比强烈的颜色;
  • 一种主要的字体颜色,和整体主色对比明显,可读性强;
  • 第二种主要字体颜色就是白色或者黑色,取决于整体主色的亮度,可读性强。

这篇文章主要讲的也就是怎么选择这些颜色。

主色

根据以上我的需求,我决定使用以下因素的平均值:

  • 鲜艳度;
  • 热度(受欢迎程度)。
鲜艳度

这个其实也很简单,首先要把RGB颜色模型转化成HSV颜色模型,使用Android内置的[Color.RGBToHSV()] (https://developer.android.com/reference/android/graphics/Color.html#RGBToHSV(int, int, int, float[]))方法可以做到。如果不明白HSV颜色模型可以看 这里

简单地说,这个圆柱形就代表了RGB颜色模型,通过三个坐标来表示颜色:Hue,Saturation和Value(明度)。

HSV_color_solid_cylinder_alpha_lowgamma

HSV颜色模型,来自 Wikipedia

我使用一个简单的方式去计算鲜艳度,通过饱和度(saturation )和色度(value)。在人眼看来这两个值越高,鲜艳度就越高。

 
 
  1. public float[] getHsv() {  
  2.     float[] hsv = new float[3]; 
  3.     Color.RGBToHSV(r, g, b, hsv); 
  4.     return hsv; 
  5.   
  6. public float calculateColorfulness() {  
  7.     float[] hsv = getHsv(); 
  8.     return hsv[1] * hsv[2]; 

计算的结果会在0.0到1.0的范围内。

热度

还记得之前说过每个颜色都有一个绑定的值吗?这里可以使用这个值来决定一种颜色在调色板中的受欢迎程度。记住值得范围是在0.0到1.0之间。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值