2012-07-20 95 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