自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

關(guān)于Android配色 自適應(yīng)顏色的實(shí)現(xiàn)

移動(dòng)開(kāi)發(fā) Android
在Android4.4系統(tǒng)中,更加詳細(xì)地介紹了關(guān)于顏色的細(xì)節(jié)并提供了使用colour的新教程,以使我們的應(yīng)用更加獨(dú)一無(wú)二。也就是說(shuō),作為一個(gè)設(shè)計(jì)師或者開(kāi)發(fā)者,為你的APP做完美的配色已經(jīng)變成了你的職責(zé)。

在Android4.4系統(tǒng)中,更加詳細(xì)地介紹了關(guān)于顏色的細(xì)節(jié)并提供了使用colour的新教程,以使我們的應(yīng)用更加獨(dú)一無(wú)二。也就是說(shuō),作為一個(gè)設(shè)計(jì)師或者開(kāi)發(fā)者,為你的APP做完美的配色已經(jīng)變成了你的職責(zé)。

可以通過(guò)改變Android Framework界面元素的默認(rèn)藍(lán)色來(lái)使應(yīng)用更加獨(dú)特。 ——來(lái)自Android Design

最簡(jiǎn)單的方式就是給Action Bar加上一層自定義的背景,但是在我現(xiàn)在寫的一個(gè)APP中我希望可以更靈活一些(做到自適應(yīng)),自適應(yīng)顏色的最好例子就是iTunes了,它會(huì)從專輯中獲取配色方案,作用于彈出的曲目列表。

color-matching-itunes

所以,我準(zhǔn)備在Android上實(shí)現(xiàn)這個(gè)技術(shù)。

基本理論知識(shí)

在網(wǎng)上搜索一遍后,我發(fā)現(xiàn)了很多開(kāi)源的實(shí)現(xiàn)方式,不過(guò)是用其他語(yǔ)言寫的。最好的版本是一個(gè)JavaScript庫(kù),叫Color Thief,我從里面學(xué)到了很多實(shí)現(xiàn)這個(gè)技術(shù)需要的知識(shí),正好是我需要的。

圖像量化

這里要做的第一步就是量化源圖像,通俗地說(shuō),就是減少圖像上使用的顏色種類。如果你喜歡動(dòng)態(tài)的GIF,那么只能用8位的色板,所以每一幀最多可以使用256種顏色。

為此,我們就需要減少顏色使用,只使用一些主要的顏色,那我們就用默認(rèn)的色板吧,再根據(jù)需要弄出一些其他的顏色。稍后將詳細(xì)介紹。

現(xiàn)在需要選擇量化算法了,Color Thief用了一個(gè)修改版的MCQ(Median Cut Quantization)算法,另稱作MMCQ(Modified Median Cut Quantization),如果想了解更多關(guān)于MMCQ的信息,可以來(lái) 這里 。其他的比較著名的量化技術(shù)還有NeuQuantOctTree。

我還在《Principles of Digital Image Processing 》這本書上找到了一個(gè)JAVA的MCQ實(shí)現(xiàn),托管在GitHub上。

這個(gè)MCQ算法有很多很棒的特性,所以我決定就用它了:

  • 它很快。它比NeuQuant和OctTree還快,在移動(dòng)設(shè)備上這點(diǎn)尤其重要;
  • 它內(nèi)部使用了統(tǒng)計(jì)直方圖,每種色塊都綁定了一個(gè)數(shù)值,之后排序的時(shí)候更方便。

雖然MCQ算法生成的圖像質(zhì)量不是最好的,但是這里只是需要它生成的調(diào)色板,不用展示生成的圖像,所以,還不錯(cuò)。

處理結(jié)果

以下就是處理后的結(jié)果,使用Color Thief的例子里的圖像。之前說(shuō)過(guò)MCQ里面帶有統(tǒng)計(jì)直方圖,所以我們可以排列出每種顏色使用的頻率,它顯示了調(diào)色板排序后的列表。當(dāng)然,這還是可以繼續(xù)改進(jìn)。

color-matching-result-1

color-matching-result-2

color-matching-result-3

這些結(jié)果和Color Thief生成的圖像有點(diǎn)不一樣:

  • 我的版本選擇藍(lán)色作為主要的顏色;
  • Color Thief挑選了藍(lán)色,銀色和綠色作為主要顏色;
  • Color Thief沒(méi)有選到那些灰色的陰影。所以還需要改進(jìn)。

接著上文講的,可以調(diào)用MedianCutQuantizer對(duì)象的getQuantizedColors()這個(gè)方法可以獲取調(diào)色板。我們可以以顏色使用的數(shù)量和比重來(lái)對(duì)這個(gè)集合進(jìn)行降序顯示。很不幸的是結(jié)果表明大多數(shù)圖像用的顏色是黑色和白色(或相近的顏色),這顏色根本不能讓我們的應(yīng)用顯得更獨(dú)特,所以我們要考慮到底選擇什么顏色了。

對(duì)于我自己的應(yīng)用來(lái)說(shuō),我準(zhǔn)備使用以下的調(diào)色方案:

  • 第一位的主色是一種鮮艷的顏色;
  • 第二位主色是區(qū)別一于第一位主色的另一種亮色;
  • 第三位主色是和第一位和第二位主色對(duì)比強(qiáng)烈的顏色;
  • 一種主要的字體顏色,和整體主色對(duì)比明顯,可讀性強(qiáng);
  • 第二種主要字體顏色就是白色或者黑色,取決于整體主色的亮度,可讀性強(qiáng)。

這篇文章主要講的也就是怎么選擇這些顏色。

主色

根據(jù)以上我的需求,我決定使用以下因素的平均值:

  • 鮮艷度;
  • 熱度(受歡迎程度)。
鮮艷度

這個(gè)其實(shí)也很簡(jiǎn)單,首先要把RGB顏色模型轉(zhuǎn)化成HSV顏色模型,使用Android內(nèi)置的[Color.RGBToHSV()] (https://developer.android.com/reference/android/graphics/Color.html#RGBToHSV(int, int, int, float[]))方法可以做到。如果不明白HSV顏色模型可以看 這里。

簡(jiǎn)單地說(shuō),這個(gè)圓柱形就代表了RGB顏色模型,通過(guò)三個(gè)坐標(biāo)來(lái)表示顏色:Hue,Saturation和Value(明度)。

HSV_color_solid_cylinder_alpha_lowgamma

HSV顏色模型,來(lái)自 Wikipedia

我使用一個(gè)簡(jiǎn)單的方式去計(jì)算鮮艷度,通過(guò)飽和度(saturation )和色度(value)。在人眼看來(lái)這兩個(gè)值越高,鮮艷度就越高。

  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]; 

計(jì)算的結(jié)果會(huì)在0.0到1.0的范圍內(nèi)。

熱度

還記得之前說(shuō)過(guò)每個(gè)顏色都有一個(gè)綁定的值嗎?這里可以使用這個(gè)值來(lái)決定一種顏色在調(diào)色板中的受歡迎程度。記住值得范圍是在0.0到1.0之間。

也就是說(shuō)我們得到了如下的簡(jiǎn)單的調(diào)色板:

|  Color   |  Count  |
----------------------
|  White   |   200   |
|  Purple  |   175   |
|  Black   |   150   |
|  Red     |   125   |
|  Orange  |   100   |
|  Blue    |    50   |
----------------------
|  Total   |   800   |

我們可以通過(guò)圖像中的這個(gè)比例來(lái)計(jì)算出顏色占有的比例,上圖中有800像素,以紫色為例,它的顏色比例為:175 / 800 = ~0.22??墒沁@個(gè)值很小,只能接近1而已。

反之我們可以選擇調(diào)色板中最受歡迎的顏色作為基準(zhǔn)來(lái)計(jì)算這個(gè)比例。還是用上一個(gè)例子,白色是最受歡迎的顏色,所以紫色的比例就是:175 / 200 = 0.87。相對(duì)于顏色的受歡迎程度來(lái)說(shuō),這個(gè)更具代表性。

最終值

這里要使用這些值來(lái)結(jié)合成一個(gè)最終的值,這樣簡(jiǎn)單合成沒(méi)有問(wèn)題,但是之前說(shuō)了黑白色是最受歡迎的顏色,考慮到這個(gè),這里我們做一個(gè)權(quán)重,來(lái)決定一些屬性的重要程度,這種情況下我們提高了鮮艷度:

  1. static float weightedAverage(float... values) {  
  2.     assert values.length % 2 == 0
  3.   
  4.     float sum = 0
  5.     float sumWeight = 0
  6.   
  7.     for (int i = 0; i = SECONDARY_MIN_DIFF_HUE_PRIMARY) { 
  8.         return candidate; 
  9.     } 
  10.   
  11. // If we get here, just return the second weighted color 
  12. return mWeightedPalette[1];   

第三位主色

這種顏色和上面第二位主色很相似,但是這次就不找Hue值了,我們直接對(duì)比前兩種顏色就可以了。

  1. // Contrast values are in the range 0-255. 
  2. private static final int TERTIARY_MIN_CONTRAST_PRIMARY = 20;  
  3. private static final int TERTIARY_MIN_CONTRAST_SECONDARY = 90
  4. ... 
  5.  // Find the first color which has sufficient contrast from both the primary & secondary 
  6. for (ColorNode color : mWeightedPalette) {  
  7. if (ColorUtils.calculateContrast(color, primary) 
  8.             >= TERTIARY_MIN_CONTRAST_PRIMARY 
  9.         && ColorUtils.calculateContrast(color, secondary) 
  10.             >= TERTIARY_MIN_CONTRAST_SECONDARY) { 
  11.     return color.getRgb(); 
  12. // We couldn't find a colour. In that case use the primary colour, modifying it's 
  13. // brightness by 45% 
  14. return ColorUtils.changeBrightness(secondary.getRgb(), 0.45f);  

來(lái)看一下,calculateContrast()這個(gè)方法哪來(lái)的?這個(gè)我也想了很久,其實(shí)它來(lái)自這篇文章 color contrast。

最后我再把RGB顏色模型轉(zhuǎn)換成了YIQ顏色模型,僅僅攜帶了Y(亮度)值,之后你可以對(duì)比下兩種顏色的亮度值,看看在明度上有什么不一樣,再用臨界值來(lái)試試。

  1. /** 
  2.  * @return difference in luma. Possible values are 0 (no difference) to 
  3.  *         255 (max difference). 
  4.  */ 
  5. private static final int calculateContrast(int rgbColor1, int rgbColor2) {  
  6.     return Math.abs(calculateYiqLuma(rgbColor1) - calculateYiqLuma(rgbColor2)); 
  7.   
  8. /** 
  9.  * @return luma value. Values are in the range 0-255. 
  10.  */ 
  11. public static final int calculateYiqLuma(int color) {  
  12.     return (299 * Color.red(color) + 587 * Color.green(color) + 114 * Color.green(color)) / 1000

代碼

我說(shuō)過(guò)要發(fā)代碼的,看這里:

https://gist.github.com/chrisbanes/ba8e7b9ec0e40f6949c6

這代碼也許跑不起來(lái),所以需要修改一下然后包含到你的APP中,這是僅僅是為了讓你知道怎么把它集成到APP中,所有重要的東西都在這里了,你只需要考慮怎么集成進(jìn)你的APP就行了。加油吧。

原文鏈接: banes   翻譯: 伯樂(lè)在線 - chris

譯文鏈接: http://blog.jobbole.com/64715/

責(zé)任編輯:閆佳明 來(lái)源: blog.jobbole
相關(guān)推薦

2011-05-12 11:28:20

按比例縮放

2022-10-24 17:57:06

CSS容器查詢

2014-09-05 10:10:32

Android自適應(yīng)布局設(shè)計(jì)

2023-10-23 08:48:04

CSS寬度標(biāo)題

2017-06-06 10:30:12

前端Web寬度自適應(yīng)

2017-08-16 14:08:46

Android O圖標(biāo)視覺(jué)

2025-01-21 08:00:00

自適應(yīng)框架框架開(kāi)發(fā)

2020-02-21 13:55:35

CSS分隔線前端

2023-07-31 08:24:34

MySQL索引計(jì)數(shù)

2010-08-30 10:26:20

DIV自適應(yīng)高度

2012-05-09 10:58:25

JavaMEJava

2010-08-30 09:52:03

DIV高度自適應(yīng)

2011-12-27 10:18:31

Web

2009-04-23 11:24:09

2015-06-08 10:49:04

2023-08-28 08:00:45

2010-08-30 09:22:13

DIV高度自適應(yīng)

2022-04-12 07:48:57

云技術(shù)SDN網(wǎng)絡(luò)

2024-05-22 09:31:07

2020-09-14 11:23:48

人工智能
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)