1

我正在构建一个工具,我从图像中选择主色并且我做得很好,我现在面临的问题是如何将返回的颜色组合成一个广泛的调色板范围,如 X11 颜色范围http: //en.wikipedia.org/wiki/Web_colors#X11_color_names

因此,例如,如果我得到:颜色 RGB:rgb(102,102,153),我想将其归为紫色,将 rgb(51,102,204) 归为蓝色,依此类推。现在我真的不知道该怎么做。是否有图书馆或我可以使用的东西,或者我应该如何编码?我正在使用 imagemagick 和 php 顺便说一句。

是否可以为每种基色生成一个包含 rgb 范围的数组,然后查看我的新颜色是否在其中?

提前谢谢各位!

4

2 回答 2

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;

?>
于 2012-07-21T19:58:42.083 回答
0

好的,忘记前面的代码,这是我从几个来源汇总的更可靠的版本,它也使用更常见的 0-360 作为色调。

我还添加了一个测试小程序,它选择随机颜色然后“告诉”你它们是什么!

似乎更可靠,可能需要围绕截止值进行一些摆弄(尤其是橙色/灰色等)。我使用这个在线颜色选择器进行测试。

<?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>";

?>
于 2012-07-23T19:44:03.303 回答