2009-11-20 18 views
16

In PHP, qual è il modo più semplice per convertire una tripletta RGB in valori HSV?da RGB a HSV in PHP

+6

Una ricerca google veloce ha trovato http://delphi.about.com/od/adptips2006/qt/RgbToHsb.htm. Non in PHP, ma è tutto matematico quindi dovrebbe essere facile. – mk12

risposta

14
<?php 
function RGB_TO_HSV ($R, $G, $B) // RGB Values:Number 0-255 
{         // HSV Results:Number 0-1 
    $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 = ((($var_Max - $var_R)/6) + ($del_Max/2))/$del_Max; 
     $del_G = ((($var_Max - $var_G)/6) + ($del_Max/2))/$del_Max; 
     $del_B = ((($var_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; 
} 
+0

Ho riordinato alcuni errori in questo codice, l'ho verificato rispetto ai risultati noti e funziona perfettamente. Grazie! –

+0

Sto cercando di capire come funziona HSV. Prima di restituire i valori, non devi moltiplicare $ H per 360 e $ S e $ V per 100? –

+0

@JackHumphries - Vedi la mia risposta per una versione leggermente più semplice da seguire, che restituisce anche gradi e percentuali. – Unsigned

29

Ecco un metodo semplice e diretto che restituisce valori HSV come gradi e percentuali, che è quello che utilizza il selettore di colori di Photoshop.

Si noti che i valori di ritorno non sono arrotondati, è possibile farlo da soli, se necessario. Tenete a mente che H(360) == H(0), così H valori di 359.5 e una maggiore dovrebbe rotonda per 0

fortemente documentata a fini di apprendimento.

/** 
* Licensed under the terms of the BSD License. 
* (Basically, this means you can do whatever you like with it, 
* but if you just copy and paste my code into your app, you 
* should give me a shout-out/credit :) 
*/ 

<?php 

function RGBtoHSV($R, $G, $B) // RGB values: 0-255, 0-255, 0-255 
{        // HSV values: 0-360, 0-100, 0-100 
    // Convert the RGB byte-values to percentages 
    $R = ($R/255); 
    $G = ($G/255); 
    $B = ($B/255); 

    // Calculate a few basic values, the maximum value of R,G,B, the 
    // minimum value, and the difference of the two (chroma). 
    $maxRGB = max($R, $G, $B); 
    $minRGB = min($R, $G, $B); 
    $chroma = $maxRGB - $minRGB; 

    // Value (also called Brightness) is the easiest component to calculate, 
    // and is simply the highest value among the R,G,B components. 
    // We multiply by 100 to turn the decimal into a readable percent value. 
    $computedV = 100 * $maxRGB; 

    // Special case if hueless (equal parts RGB make black, white, or grays) 
    // Note that Hue is technically undefined when chroma is zero, as 
    // attempting to calculate it would cause division by zero (see 
    // below), so most applications simply substitute a Hue of zero. 
    // Saturation will always be zero in this case, see below for details. 
    if ($chroma == 0) 
     return array(0, 0, $computedV); 

    // Saturation is also simple to compute, and is simply the chroma 
    // over the Value (or Brightness) 
    // Again, multiplied by 100 to get a percentage. 
    $computedS = 100 * ($chroma/$maxRGB); 

    // Calculate Hue component 
    // Hue is calculated on the "chromacity plane", which is represented 
    // as a 2D hexagon, divided into six 60-degree sectors. We calculate 
    // the bisecting angle as a value 0 <= x < 6, that represents which 
    // portion of which sector the line falls on. 
    if ($R == $minRGB) 
     $h = 3 - (($G - $B)/$chroma); 
    elseif ($B == $minRGB) 
     $h = 1 - (($R - $G)/$chroma); 
    else // $G == $minRGB 
     $h = 5 - (($B - $R)/$chroma); 

    // After we have the sector position, we multiply it by the size of 
    // each sector's arc (60 degrees) to obtain the angle in degrees. 
    $computedH = 60 * $h; 

    return array($computedH, $computedS, $computedV); 
} 

?> 
+0

Risposta stupenda. Era proprio quello che avevo bisogno di imparare come calcolare la parte del valore di HSV. Ty. – Deanie

+0

C'è un modo per invertire questo processo, riconvertendolo? – JacobTheDev

+0

@JacobTheDev Naturalmente. [Questa domanda] (https://stackoverflow.com/q/3018313/629493) ha esempi. – Unsigned