2011-11-21 25 views
7

我很感興趣的算法是在兩個給定顏色之間生成'n'漸變顏色,這些顏色在每個顏色之間生成平滑過渡。在PHP中生成RGB漸變色的算法

我試着讓靜態兩個通道,例如R和G,以及增量變化B,但有時兩種顏色之間的差異比鄰居更難。

我想檢查不同的算法並分析它們的弱點和強度。


我寫了這個代碼,它似乎邏輯,但一些顏色之間的過渡比其他之間更硬(egbetween 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 
} 
?> 

是有更好的算法來做到這一點?


我帶來的例子:另外,在上述我用$c1=array(192,5,248);$c2 = array(142,175,240);$nc = 10;和獲得該圖像的代碼:

graduated colors example

的0,1,8的RGB值和9是:

  • 0 = 192,5,248
  • 1 = 186,24,247
  • 8 = 148156241
  • 9 = 142175240

如果你看那裏是6,19,1相鄰顏色之間的性差異。但0到1之間的視覺過渡比8到9之間的過渡要柔和。對於HSV來說也是一樣的。這是一些顏色,使其過渡更硬或更軟。

+0

所以....你到目前爲止嘗試過什麼? – Fosco

+0

什麼是「我嘗試讓靜態兩個通道,例如R和G,以及增量更改B」是什麼意思?你是否保持R和G相同,只改變B?這隻有在R和G在源和目標顏色相同的情況下才有效。 – mcrumley

+0

是@mcrumley,我做過了,但後來發現最好是分開渠道之間的差異。請看看添加的代碼。 – Memochipan

回答

4

在下面的圖片你可以看到一段代碼的輸出我寫信給使用RGB和HSV分裂相等大小的步驟兩種顏色之間的對比轉換:

enter image description here

我發現使用過渡HSV受色相影響,取決於顏色之間的距離。如果選擇具有相同色調的兩種顏色,可以發現HSV過渡比RGB更清晰,因爲您只是在玩飽和度和數值(黑色),並且沒有像RGB那樣添加顏色。

<?php 
// Configuration. 
$nc = 6; // Number of colors. 
$w = 300; // Width of divs. 
$a = 50; // Height of divs. 

// Colors 
/* In RGB */ 
$c1 = array(rand(0,255),rand(0,255),rand(0,255)); 
$c2 = array(rand(0,255),rand(0,255),rand(0,255)); 
//$c1 = array(128,175,27); // Color 1: Whit these colors is not change. 
//$c2 = array(255,255,140); // Color 2: Whit these colors is not change. 
// $c1 = array(0,0,0); // Color 1: White. 
// $c2 = array(255,255,255); // Color 2: Black. 
/* In HSV */ 
$h3 = array(rand(0,360),rand(0,100),rand(0,100)); 
$h4 = array(rand(0,360),rand(0,100),rand(0,100)); 
//$h3 = array(145,50,50); // Color 3: To see the influence of Hue. 
//$h4 = array(145,0,100); // Color 4: To see the influence of Hue. 

// HTML 
$html .= '<div style="margin:auto;width:'.($w*2).'px;">'; 
// RGB to RGB split 
$c = graduateRGB($c1,$c2,$nc); 
$html .= customHTML($w,$a,$c,'RGB->RGBs'); 
// RGB to HSV split 
$h1 = RGBtoHSV($c1); 
$h2 = RGBtoHSV($c2); 
$h = graduateHSV($h1,$h2,$nc); 
$html .= customHTML($w,$a,$h,'RGB->HSVs'); 
// HSV to HSV split 
$h = graduateHSV($h3,$h4,$nc); 
$html .= customHTML($w,$a,$h,'HSV->HSVs'); 
// HSV to RGB split 
$c3 = HSVtoRGB($h3); 
$c4 = HSVtoRGB($h4); 
$c = graduateRGB($c3,$c4,$nc); 
$html .= customHTML($w,$a,$c,'HSV->RGBs'); 
// Output 
$html .= '</div>'; 
echo $html; 

/* FUNCIONES DE GRADUACIÓN */ 
// Dados dos colores RGB (0-255,0-255,0-255) y un número de colores deseados, regresa un array con todos los colores de la gradación. 
function graduateRGB($c1,$c2,$nc){ 
    $c = array(); 
    $dc = array(($c2[0]-$c1[0])/($nc-1),($c2[1]-$c1[1])/($nc-1),($c2[2]-$c1[2])/($nc-1)); 
    for ($i=0;$i<$nc;$i++){ 
     $c[$i][0]= round($c1[0]+$dc[0]*$i); 
     $c[$i][1]= round($c1[1]+$dc[1]*$i); 
     $c[$i][2]= round($c1[2]+$dc[2]*$i); 
    } 
    return $c; 
} 
// Dados dos colores HSV (0-360,0-100,0-100) y un número de colores deseados, regresa un array con todos los colores de la gradación en RGB. (Hay un detalle con esta función y es que la transición se podría hacer por el lado contrario del círculo cromático) 
function graduateHSV($h1,$h2,$nc){ 
    $h = array(); 
    $dh = array(($h2[0]-$h1[0])/($nc-1),($h2[1]-$h1[1])/($nc-1),($h2[2]-$h1[2])/($nc-1)); 
    for ($i=0;$i<$nc;$i++){ 
     $h[$i][0]= $h1[0]+$dh[0]*$i; 
     $h[$i][1]= $h1[1]+$dh[1]*$i; 
     $h[$i][2]= $h1[2]+$dh[2]*$i; 
     $h[$i] = HSVtoRGB($h[$i]); 
    } 
    return $h; 
} 

/* FUNCIONES DE CONVERSIÓN. */ 
// Convierte a HSV (0-360,0-100,0-100) colores en RGB (0-255,0-255,0-255). 
function RGBtoHSV(array $rgb) { 

    $f = 0.00000001; // Factor de corrección para evitar la división por cero. 

    list($R,$G,$B) = $rgb; 

    $R = $R==0?$f:$R/255; 
    $G = $G==0?$f:$G/255; 
    $B = $B==0?$f:$B/255; 

    $V = max($R,$G,$B); 
    $X = min($R,$G,$B); 
    $S = ($V-$X)/$V; 

    $V_X = $V-$X==0?$f:$V-$X; 

    $r = ($V-$R)/($V_X); 
    $g = ($V-$G)/($V_X); 
    $b = ($V-$B)/($V_X);  

    if ($R == $V) 
     $H = $G==$X?(5+$b):(1-$g); 
    elseif ($G == $V) 
     $H = $B==$X?(1+$r):(3-$b); 
    else 
     $H = $R==$X?(3+$g):(5-$r); 

    $H /= 6; 

    $H = round($H*360); 
    $S = round($S*100); 
    $V = round($V*100); 

    return array($H, $S, $V); 
} 

// Convierte a RGB (0-255,0-255,0-255) colores en HSV (0-360,0-100,0-100). 
function HSVtoRGB(array $hsv) { 
    list($H,$S,$V) = $hsv; 

    $H = $H/360; 
    $S = $S/100; 
    $V = $V/100; 

    //1 
    $H *= 6; 
    //2 
    $I = floor($H); 
    $F = $H - $I; 
    //3 
    $M = $V * (1 - $S); 
    $N = $V * (1 - $S * $F); 
    $K = $V * (1 - $S * (1 - $F)); 
    //4 
    switch ($I) { 
     case 0: 
      list($R,$G,$B) = array($V,$K,$M); 
      break; 
     case 1: 
      list($R,$G,$B) = array($N,$V,$M); 
      break; 
     case 2: 
      list($R,$G,$B) = array($M,$V,$K); 
      break; 
     case 3: 
      list($R,$G,$B) = array($M,$N,$V); 
      break; 
     case 4: 
      list($R,$G,$B) = array($K,$M,$V); 
      break; 
     case 5: 
     case 6: //for when $H=1 is given 
      list($R,$G,$B) = array($V,$M,$N); 
      break; 
    } 

    $R = round($R*255); 
    $G = round($G*255); 
    $B = round($B*255); 

    return array($R, $G, $B); 
} 

// Función con un HTML de muestra para la visualización de colores, podría ser cualquier otro. 
function customHTML($w,$a,$c,$header){ 
    $html = '<div style="float:left;text-align:center;"><h2>'.$header.'</h2>'; 
    foreach ($c as $color){ 
     $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>'; 
    } 
    $html .= '</div>'; 
    return $html; 
} 
?> 
4

在HSV中,生成n種顏色,其色調從第一種顏色線性變化爲第二種顏色。將每個HSV值轉換爲RGB。

+0

你能建議一種方法來做到這一點在PHP中?看看我上面的示例代碼?你建議的方式比這更好?感謝您的回答。 – Memochipan

+0

沒有什麼PHP特有的。在HSV和RGB之間切換隻是簡單的算法。 Google是你的朋友。或者,請參閱http://stackoverflow.com/q/3597447/21727 – mbeckish

+0

在給定兩種RGB顏色的情況下,我看不到任何優勢,請轉換爲HSV再重新轉換爲RGB。我測試了你說的話,但是改變了V而不是H,步長爲10,結果和我上面的代碼完全一樣。 – Memochipan