在Android4.4系统中,我们更详细地介绍了关于颜色的细节,并提供了一个新的颜色使用教程,使我们的应用程序更加独特。换句话说,作为设计师或开发者,为你的应用做出完美的配色已经成为你的责任。您可以通过更改AndroidFramework界面元素的默认蓝色来使您的应用程序更加独特。——来自AndroidDesign最简单的方法就是在ActionBar上加一层自定义背景,但是在我现在写的一个APP中,希望可以更加灵活(自适应),自适应颜色就是最好的一个例子是iTunes,它从专辑中获取配色方案并将其应用于弹出的曲目列表。所以,我打算在Android上实现这个技术。在网上搜索基础理论知识后,发现很多开源的实现,但是都是用其他语言写的。最好的版本是一个名为ColorThief的JavaScript库,我从中学到了很多东西来实现这项技术,这正是我所需要的。图像量化这里要做的第一步是量化源图像。通俗地说,就是减少图像上使用的颜色种类。如果您喜欢GIF动画,只有8位样本可用,因此每帧最多可以使用256种颜色。为此,我们需要减少颜色的使用,只使用一些主要颜色,所以让我们使用默认的调色板,然后根据需要制作一些其他颜色。稍后会详细介绍。现在您需要选择一种量化算法。ColorThief使用MCQ(中值切割量化)算法的修改版本,也称为MMCQ(改进的中值切割量化)。如果你想了解更多关于MMCQ的信息,可以来这里。其他著名的量化技术包括NeuQuant和OctTree。我还在GitHub上托管的《Principles of Digital Image Processing 》书中找到了MCQ的JAVA实现。这个MCQ算法有很多很好的特性,所以我决定只使用它:它很快。它比NeuQuant和OctTree更快,这在移动设备上尤为重要;内部使用统计直方图,每个色块绑定一个值,方便后期排序。虽然MCQ算法生成的图像质量不是最好的,但这里只是用它生成的调色板,并没有显示生成的图像,所以还算不错。处理后的结果下面是使用ColorThief示例中的图像处理后的结果。前面说过,MCQ中有一个统计直方图,所以我们可以对每种颜色的频率进行排序,它显示了排序后的调色板列表。当然,这个还是可以改进的。这些结果与ColorThief生成的图像有点不同:我的版本选择蓝色作为主色;ColorThief以蓝色、银色和绿色为主色调;ColorThief不会选择那些灰色阴影。所以还有改进的余地。按照上面的方法,您可以调用MedianCutQuantizer对象的getQuantizedColors()方法来获取调色板。我们可以按照颜色使用量和权重的降序显示这个集合。不幸的是,大多数使用的图像都是黑白的(或接近黑白的),这并不能使我们的应用程序更加独特,因此我们必须考虑选择什么颜色。对于我自己的应用程序,我计划使用以下配色方案:第一个主色是明亮的颜色;第二主色为不同于第一主色的另一种鲜艳的颜色。第三主色是与第一、第二主色对比强烈的颜色;主字体颜色,与整体主色对比鲜明,可读性强;第二主字体颜色为白色或黑色,取决于整体主色的亮度,可读性强。本文主要讲的是如何选择这些颜色。主色根据我的上述需求,我决定使用以下因素的平均值:Vibrance;热度(人气)。生动其实很简单。首先,将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颜色模型,来自维基百科我使用一种简单的方法来计算鲜艳度,通过饱和度(saturation)和色调(value)。这两个值越高,在人眼看来,鲜艳度就越高。publicfloat[]getHsv(){float[]hsv=newfloat[3];Color.RGBToHSV(r,g,b,hsv);returnhsv;}publicfloatcalculateColorfulness(){float[]hsv=getHsv();returnhsv[1]*hsv[2];}计算结果将在0.0到1.0的范围内。热还记得我说过每种颜色都有一个绑定值吗?此值可在此处用于确定颜色在调色板中的流行程度。请记住,值范围介于0.0和1.0之间。这意味着我们得到一个像这样的简单调色板:|颜色|计数|------------------------|白色|200||紫色|第175章黑色|150||红色|125||橙色|100||蓝色|50|------------------------|总计|800|我们可以通过这个比例来计算颜色在图像中的比例。上图有800个像素。以紫色为例,其颜色比例为:175/800=~0.22。但是这个值很小,只接近于1。相反,我们可以选择调色板中最流行的颜色作为基准来计算这个比例。使用前面的示例,白色是最受欢迎的颜色,因此紫色的比例为:175/200=0.87。相对于流行色来说,这个更具有代表性。这里的finalvalue就是用这些值组合成一个finalvalue,所以简单合成是没有问题的,不过之前说过黑色和白色是最流行的颜色,考虑到这一点,这里我们做一个权重来确定一些属性的重要性在这种情况下,我们增加生动性:staticfloatweightedAverage(float...values){assertvalues.length%2==0;floatsum=0;floatsumWeight=0;for(inti=0;i=SECONDARY_MIN_DIFF_HUE_PRIMARY){returncandidate;}}//如果wegethere,只返回第二个加权颜色returnmWeightedPalette[1];第三个主色和上面的第二个主色很像,不过这次我们不去寻找Hue值,直接比较前两个颜色就可以了。//Contrastvaluesareintherange0-255.privatestaticfinalintTERTIARY_MIN_CONTRAST_PRIMARY=20;privatestaticfinalintTERTIARY_MIN_CONTRAST_SECONDARY=90;...//Findthefirstcolorwhichhassufficientcontrastfromboththeprimary&secondaryfor(ColorNodecolor:mWeightedPalette){if(ColorUtils.calculateContrast(color,primary)>=TERTIARY_MIN_CONTRAST_PRIMARY&&ColorUtils.calculateContrast(color,secondary)>=TERTIARY_MIN_CONTRAST_SECONDARY){returncolor.getRgb();}}//我们找不到颜色。在这种情况下使用原色,修改它的//亮度为45%returnColorUtils.changeBrightness(secondary.getRgb(),0.45f);让我们看看,calculateContrast()方法从哪里来?这个我也想了很久,其实就是出自这篇文章色彩对比。最后我把RGB颜色模型转成YIQ颜色模型,只带了Y(亮度)值,然后你可以比较两种颜色的亮度值,看看亮度有什么不同,然后用critical值得尝试。/***@returndifferenceinluma.Possiblevaluesare0(nodifference)to*255(maxdifference).*/privatestaticfinalintcalculateContrast(intrgbColor1,intrgbColor2){returnMath.abs(calculateYiqLuma(rgbColor1)-calculateYiqLuma(rgbColor2));}/***value@returnValuesareintherange0-255.*/publicstaticfinalintcalculateYiqLuma(intcolor){return(299*Color.red(color)+587*Color.green(color)+114*Color.green(color))/1000;}我说的发代码代码见这里:https://gist.github.com/chrisbanes/ba8e7b9ec0e40f6949c6这段代码可能无法运行,所以你需要修改它并将其包含在你的APP中,这只是为了让你知道如何集成它在APP里,重要的都在这里,你只需要考虑如何融入你的APP。快点。原文链接:Banes翻译:伯乐在线-Chris翻译链接:http://blog.jobbole.com/64715/
