在PHP中生成RGB渐变颜色的算法

Mem*_*pan 7 php algorithm rgb colors

我很有兴趣在两种给定颜色之间生成'n'渐变颜色的算法,它们在每种颜色之间产生平滑过渡.

我试过让静态的两个通道,例如R和G,以及增量变化B,但有时两种颜色之间的差异比邻居更难.

我想检查不同的算法并分析它们的弱点和强度.


我写了这段代码似乎是逻辑,但是某些颜色之间的转换比其他颜色之间的转换更难(例如0到1之间比1到2之间更难):

<?php
$c1 = array(128,175,27); // Color 1
$c2 = array(255,255,140); // Color 2
$nc = 5; // Number of colors to display.
$dc = array(($c2[0]-$c1[0])/($nc-1),($c2[1]-$c1[1])/($nc-1),($c2[2]-$c1[2])/($nc-1)); // Step between colors

for ($i=0;$i<$nc;$i++){
    echo '<div style="width:200px;height:50px;background-color:rgb('.round($c1[0]+$dc[0]*$i).','.round($c1[1]+$dc[1]*$i).','.round($c1[2]+$dc[2]*$i).');">'.$i.'</div>'; // Output
}
?>
Run Code Online (Sandbox Code Playgroud)

有没有更好的算法来做到这一点?


我带来一个例子:在上面的代码我用$c1=array(192,5,248);$c2 = array(142,175,240);$nc = 10;和获得该图像:

渐变色的例子

RGB值0,1,8和9是:

  • 0 = 192,5,248
  • 1 = 186,24,247
  • 8 = 148,156,241
  • 9 = 142,175,240

如果你看,6,19,1的相邻颜色之间存在差异.但是0和1之间的视觉转换比8和9之间的转换更柔和.而对于HSV则是相同的.它是某种颜色的东西,它的过渡更难或更柔和.

Mem*_*pan 4

在下图中,您可以看到我编写的一段代码的输出,该代码用于使用 RGB 和 HSV 以相等大小的步长分割来比较两种颜色之间的过渡:

\n\n

在此输入图像描述

\n\n

我发现使用 HSV 的过渡受到色调的影响,并且取决于颜色之间的距离。如果您选择具有相同色调的两种颜色,很有趣的是,HSV 过渡比 RGB 更清晰,因为您只使用饱和度和明度(黑色),而没有像 RGB 那样添加颜色。

\n\n
<?php\n// Configuration.\n$nc = 6; // Number of colors.\n$w = 300; // Width of divs.\n$a = 50; // Height of divs.\n\n// Colors\n/* In RGB */\n$c1 = array(rand(0,255),rand(0,255),rand(0,255));\n$c2 = array(rand(0,255),rand(0,255),rand(0,255)); \n//$c1 = array(128,175,27); // Color 1: Whit these colors is not change.\n//$c2 = array(255,255,140); // Color 2: Whit these colors is not change.\n// $c1 = array(0,0,0); // Color 1: White.\n// $c2 = array(255,255,255); // Color 2: Black.\n/* In HSV */\n$h3 = array(rand(0,360),rand(0,100),rand(0,100)); \n$h4 = array(rand(0,360),rand(0,100),rand(0,100)); \n//$h3 = array(145,50,50); // Color 3: To see the influence of Hue.\n//$h4 = array(145,0,100); // Color 4: To see the influence of Hue.\n\n// HTML\n$html .= \'<div style="margin:auto;width:\'.($w*2).\'px;">\';\n// RGB to RGB split\n$c = graduateRGB($c1,$c2,$nc);\n$html .= customHTML($w,$a,$c,\'RGB->RGBs\');\n// RGB to HSV split\n$h1 = RGBtoHSV($c1);\n$h2 = RGBtoHSV($c2);\n$h = graduateHSV($h1,$h2,$nc);\n$html .= customHTML($w,$a,$h,\'RGB->HSVs\');\n// HSV to HSV split\n$h = graduateHSV($h3,$h4,$nc);\n$html .= customHTML($w,$a,$h,\'HSV->HSVs\');\n// HSV to RGB split\n$c3 = HSVtoRGB($h3);\n$c4 = HSVtoRGB($h4);\n$c = graduateRGB($c3,$c4,$nc);\n$html .= customHTML($w,$a,$c,\'HSV->RGBs\');\n// Output\n$html .= \'</div>\';\necho $html;\n\n/* FUNCIONES DE GRADUACI\xc3\x93N */\n// Dados dos colores RGB (0-255,0-255,0-255) y un n\xc3\xbamero de colores deseados, regresa un array con todos los colores de la gradaci\xc3\xb3n.   \nfunction graduateRGB($c1,$c2,$nc){\n    $c = array();\n    $dc = array(($c2[0]-$c1[0])/($nc-1),($c2[1]-$c1[1])/($nc-1),($c2[2]-$c1[2])/($nc-1));\n    for ($i=0;$i<$nc;$i++){\n        $c[$i][0]= round($c1[0]+$dc[0]*$i);\n        $c[$i][1]= round($c1[1]+$dc[1]*$i);\n        $c[$i][2]= round($c1[2]+$dc[2]*$i);\n    }\n    return $c;\n}\n// Dados dos colores HSV (0-360,0-100,0-100) y un n\xc3\xbamero de colores deseados, regresa un array con todos los colores de la gradaci\xc3\xb3n en RGB.    (Hay un detalle con esta funci\xc3\xb3n y es que la transici\xc3\xb3n se podr\xc3\xada hacer por el lado contrario del c\xc3\xadrculo crom\xc3\xa1tico)\nfunction graduateHSV($h1,$h2,$nc){\n    $h = array();\n    $dh = array(($h2[0]-$h1[0])/($nc-1),($h2[1]-$h1[1])/($nc-1),($h2[2]-$h1[2])/($nc-1));\n    for ($i=0;$i<$nc;$i++){\n        $h[$i][0]= $h1[0]+$dh[0]*$i;\n        $h[$i][1]= $h1[1]+$dh[1]*$i;\n        $h[$i][2]= $h1[2]+$dh[2]*$i;\n        $h[$i] = HSVtoRGB($h[$i]);\n    }\n    return $h;\n}\n\n/* FUNCIONES DE CONVERSI\xc3\x93N. */\n// Convierte a HSV (0-360,0-100,0-100) colores en RGB (0-255,0-255,0-255).\nfunction RGBtoHSV(array $rgb) {\n\n    $f = 0.00000001; // Factor de correcci\xc3\xb3n para evitar la divisi\xc3\xb3n por cero.\n\n    list($R,$G,$B) = $rgb;\n\n    $R = $R==0?$f:$R/255;\n    $G = $G==0?$f:$G/255;\n    $B = $B==0?$f:$B/255;\n\n    $V = max($R,$G,$B);\n    $X = min($R,$G,$B);\n    $S = ($V-$X)/$V;\n\n    $V_X = $V-$X==0?$f:$V-$X;\n\n    $r = ($V-$R)/($V_X);\n    $g = ($V-$G)/($V_X);\n    $b = ($V-$B)/($V_X);    \n\n    if ($R == $V)\n        $H = $G==$X?(5+$b):(1-$g);\n    elseif ($G == $V)\n        $H = $B==$X?(1+$r):(3-$b);\n    else\n        $H = $R==$X?(3+$g):(5-$r);\n\n    $H /= 6;\n\n    $H = round($H*360);\n    $S = round($S*100);\n    $V = round($V*100);\n\n    return array($H, $S, $V);\n}\n\n// Convierte a RGB (0-255,0-255,0-255) colores en HSV (0-360,0-100,0-100).\nfunction HSVtoRGB(array $hsv) {\n    list($H,$S,$V) = $hsv;\n\n    $H = $H/360;\n    $S = $S/100;\n    $V = $V/100;\n\n    //1\n    $H *= 6;\n    //2\n    $I = floor($H);\n    $F = $H - $I;\n    //3\n    $M = $V * (1 - $S);\n    $N = $V * (1 - $S * $F);\n    $K = $V * (1 - $S * (1 - $F));\n    //4\n    switch ($I) {\n        case 0:\n            list($R,$G,$B) = array($V,$K,$M);\n            break;\n        case 1:\n            list($R,$G,$B) = array($N,$V,$M);\n            break;\n        case 2:\n            list($R,$G,$B) = array($M,$V,$K);\n            break;\n        case 3:\n            list($R,$G,$B) = array($M,$N,$V);\n            break;\n        case 4:\n            list($R,$G,$B) = array($K,$M,$V);\n            break;\n        case 5:\n        case 6: //for when $H=1 is given\n            list($R,$G,$B) = array($V,$M,$N);\n            break;\n    }\n\n    $R = round($R*255);\n    $G = round($G*255);\n    $B = round($B*255);\n\n    return array($R, $G, $B);\n}\n\n// Funci\xc3\xb3n con un HTML de muestra para la visualizaci\xc3\xb3n de colores, podr\xc3\xada ser cualquier otro.\nfunction customHTML($w,$a,$c,$header){\n    $html = \'<div style="float:left;text-align:center;"><h2>\'.$header.\'</h2>\';\n    foreach ($c as $color){\n        $html .= \'<div style="width:\'.$w.\'px;height:\'.$a.\'px;background-color:rgb(\'.$color[0].\',\'.$color[1].\',\'.$color[2].\');">RGB \'.$color[0].\',\'.$color[1].\',\'.$color[2].\'</div>\';\n    }\n    $html .= \'</div>\';\n    return $html;\n}\n?>\n
Run Code Online (Sandbox Code Playgroud)\n