这种颜色属于哪种X11颜色范围

时间:2012-07-20 20:32:39

标签: php colors imagemagick

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

因此,例如,如果我得到:颜色RGB:rgb(102,102,153),我想要将其粉笔化为紫色,将rgb(51,102,204)粉化为蓝色,依此类推。现在我真的无法弄清楚如何做到这一点。是否有图书馆或我可以使用的东西或我应该如何编码?我正在使用imagemagick和php btw。

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

先谢谢你们!

2 个答案:

答案 0 :(得分: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;

?>

答案 1 :(得分:0)

好的,忘记以前的代码,这是一个更可靠的版本,我从几个来源放在一起,也使用更常见的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>";

?>