2012-07-20 160 views
1

我正在構建一個工具,我從圖像中挑選主色,並且我已經做得非常好,現在我面臨的問題是如何組合返回的顏色到了廣闊的調色板範圍,如X11色彩範圍http://en.wikipedia.org/wiki/Web_colors#X11_color_names這種顏色在哪個X11顏色範圍內

因此,舉例來說,如果我有:顏色RGB:RGB(102102153),我會想記在紫色的顏色和RGB(51102204),藍色等等等。現在我真的不知道如何做到這一點。有沒有圖書館或我可以使用的東西,或者我應該如何編碼?我使用imagemagick和php btw。

是否有可能生成一個包含每個基本顏色的RGB範圍,然後看看我的新顏色在於它的數組?

在此先感謝你們!

+0

你也可以看到這個問題,比如哪個頻譜的交點是顏色在哪裏? http://upload.wikimedia.org/wikipedia/commons/thumb/c/c2/AdditiveColor.svg/200px-AdditiveColor.svg.png – Suyash 2012-07-20 22:21:09

回答

0

OK,忘掉以前的代碼,這裏是一個更可靠的版本我從幾個來源放在一起也使用了比較常見的0-360的色調。

我還添加了一個測試小程序,選擇隨機顏色,然後'告訴'你他們是什麼!

看起來更可靠,可能需要圍繞截止值(尤其是橙色/灰色等)進行一些調整。我用this online colour picker進行測試。

<?php 

function RGBtoHSL($r,$g,$b) { 
// based on code and formulas from: 
// http://www.had2know.com/technology/hsl-rgb-color-converter.html 
// http://colorgrader.net/index.php/dictionary-a-tutorials/color-theory/93-math-behind-colorspace-conversions-rgb-hsl.html 
// http://proto.layer51.com/d.aspx?f=1135 


$max = max($r, $g, $b); 
$min = min($r, $g, $b); 
$d = ($max - $min)/255; 
$lum = round((($max+$min)/2)/255, 2); 

$sat = 0; 
if ($lum > 0) $sat = round($d/(1 - (2*$lum-1)), 2); 

$hue = 0; 
if(($r==$g) && ($g==$b)) $hue = 0; 
else if($r>=$g && $g>=$b) $hue = 60*($g-$b)/($r-$b); 
else if($g>=$r && $r>=$b) $hue = 60 + 60*($g-$r)/($g-$b); 
else if($g>=$b && $b>=$r) $hue = 120 + 60*($b-$r)/($g-$r); 
else if($b>=$g && $g>=$r) $hue = 180 + 60*($b-$g)/($b-$r); 
else if($b>=$r && $r>=$g) $hue = 240 + 60*($r-$g)/($b-$g); 
else if($r>=$b && $b>=$g) $hue = 300 + 60*($r-$b)/($r-$g); 
else $hue = 0; 
$hue = round($hue, 0); 
$hsl = array(); 
$hsl['h'] = $hue; 
$hsl['s'] = $sat; 
$hsl['l'] = $lum; 
return $hsl; 
} 




// example: pick 42 random colours then identify them 
echo "<div style='float: left; width: 1000px;'>"; 

srand; 
for ($f=0; $f < 42; $f++) { 

$red = rand(0, 255); 
$green = rand(0, 255); 
$blue = rand(0, 255); 

$hsl = RGBtoHSL($red, $green, $blue); 

$hue = $hsl['h']; 
$sat = $hsl['s']; 
$lum = $hsl['l']; 

$colour = "Red";   // default to red 

if ($hue >= 11 && $hue <= 45) { 
$colour = "Orange"; 
if ($lum < 0.51) $colour = "Brown"; 
} 
if ($hue >= 46 && $hue <= 62) $colour = "Yellow"; 
if ($hue >= 63 && $hue <= 160) $colour = "Green"; 
if ($hue >= 161 && $hue <= 262) $colour = "Blue"; 
if ($hue >= 263 && $hue <= 292) $colour = "Purple"; 
if ($hue >= 293 && $hue <= 349) $colour = "Pink"; 
if ($sat < 0.07) $colour = "Grey"; // do grey before black/white 
if ($lum < 0.10) $colour = "Black"; 
if ($lum > 0.97) $colour = "White"; 

echo "<div style='float: left; width: 150px; border: 1px solid #000000; margin: 5px;'>";  
echo "<div style='float: left; width: 20px; height: 120px; background-color: rgb($red, $green, $blue); margin-right: 10px;'></div>"; 
echo "<p style='width: 33%; float: left;'>R=$red<br/>G=$green<br/>B=$blue</p>"; 
echo "<p style='width: 33%; float: right;'>H=$hue<br/>S=$sat<br/>L=$lum</p>"; 
echo "<p><b>$colour</b></p>"; 
echo "</div>"; 
} 

echo "</div>"; 

?> 
+0

尊重的辛勤工作!然而,我採取了最後一個例子,並且一直在調整代碼,添加更多具有光度和飽和度的變化,如60和160和240的邊界線值會在法庭的兩側得到。將完成後發佈我的代碼。 – Suyash 2012-07-23 21:19:48

1

我一直在爲即將到來的項目尋找完全一樣的東西,雖然我很滿意基本的彩虹顏色。

搜索周圍,最好的辦法似乎是將RGB顏色轉換爲HSL。 (H)ue部分對於瞭解顏色所在的彩虹的大部分是非常有用的。然後添加一些額外的位來捕捉黑色,白色,灰色和棕色。

這裏是我的PHP代碼,引用了RGB - > HSL轉換例程。我相信它可以優化得更好一點,但這是一個開始!

很顯然,顏色是非常主觀的,所以你可能想要玩弄每個顏色範圍的值 - 只需使用在線顏色選擇器實用程序之一,甚至是Windows顏色選擇器。

<?php 

    function RGB_TO_HSV ($R, $G, $B) { // RGB Values:Number 0-255 
            // HSV Results:Number 0-1 
    // this function from http://stackoverflow.com/questions/1773698/rgb-to-hsv-in-php 
    $HSL = array(); 

    $var_R = ($R/255); 
    $var_G = ($G/255); 
    $var_B = ($B/255); 

    $var_Min = min($var_R, $var_G, $var_B); 
    $var_Max = max($var_R, $var_G, $var_B); 
    $del_Max = $var_Max - $var_Min; 

    $V = $var_Max; 

    if ($del_Max == 0) { 
    $H = 0; 
    $S = 0; 
    } 
    else { 
    $S = $del_Max/$var_Max; 

    $del_R = ((($max - $var_R)/6) + ($del_Max/2))/$del_Max; 
    $del_G = ((($max - $var_G)/6) + ($del_Max/2))/$del_Max; 
    $del_B = ((($max - $var_B)/6) + ($del_Max/2))/$del_Max; 

    if ($var_R == $var_Max) $H = $del_B - $del_G; 
    else if ($var_G == $var_Max) $H = (1/3) + $del_R - $del_B; 
    else if ($var_B == $var_Max) $H = (2/3) + $del_G - $del_R; 

    if (H<0) $H++; 
    if (H>1) $H--; 
    } 

    $HSL['H'] = $H; 
    $HSL['S'] = $S; 
    $HSL['V'] = $V; 
    return $HSL; 
} 

// convert an RGB colour to HSL 
$hsl = RGB_TO_HSV(51,102,204);  // rgb values 0-255 

$hue = round($hsl['H'] * 255, 0); // round hue from 0 to 255 for ease of use 
$sat = $hsl['S'];      // 0 to 1 
$val = $hsl['V'];      // 0 to 1 

$colour = "Red";      // default to red 

if ($hue >= 10 && $hue <= 35) { 
    $colour = "Orange"; 
    if ($val < 0.69) $colour = "Brown"; 
} 
if ($hue >= 36 && $hue <= 44) $colour = "Yellow"; 
if ($hue >= 45 && $hue <= 107) $colour = "Green"; 
if ($hue >= 108 && $hue <= 182) $colour = "Blue"; 
if ($hue >= 183 && $hue <= 206) $colour = "Purple"; 
if ($hue >= 207 && $hue <= 245) $colour = "Pink"; 
if ($val < 0.1) $colour = "Black"; 
if ($val > 0.9) $colour = "White"; 
if ($sat < 0.105) $colour = "Grey"; 


// show the result 
echo $colour; 

?> 
+0

嘿!非常感謝我向我展示了一種新的方法,我也很喜歡彩虹的顏色,但是上面實現的當前範圍有點有缺陷,例如102,102,153應該是紫色的,但是這顯示爲藍色。 此外,你爲什麼在這個例子中四捨五入?我用的在線調色板顯示色調0-360。你能告訴我如何以及從哪裏可以拿起這些範圍的行業標準分類? – Suyash 2012-07-23 08:27:33

+0

也定義了色相介於0-255之間,但我也得到了負值。 – Suyash 2012-07-23 10:08:15

+0

色相轉換爲0-255以匹配我使用的顏色選擇器,雖然正常範圍似乎是0-360。在我做的所有測試中,它似乎確實相當準確。我不知道你爲什麼會得到負面價值。 – raymortim 2012-07-23 12:51:08