[PHP] Conversie RGB - hue/brightness/saturation

Pagina: 1
Acties:

  • Anders
  • Registratie: December 2000
  • Laatst online: 24-08 18:29
Ik wil het hele kleurenschema van een beheeromgeving aan kunnen passen op basis van 1 opgegeven uitgangskleur. Dat aanpassen wil ik doen door volautomatisch tinten te bepalen die dezelfde kleur hebben maar andere saturation- of lightness-gradaties.

Hiervoor moet ik een RGB-kleur (hexadecimaal of decimaal, maakt niet uit) kunnen converteren naar hue, brightness, saturation om vervolgens andere de waardes van de lightness en saturation te veranderen en terug te converteren naar RGB.

Ik heb op het web een aantal conversie-algoritmes gevonden, maar dat is in C of VB(script), en ik krijg het tot mijn furstratie niet aan de praat in PHP. Iemand een idee hoe ik het aan moet pakken?

Ik spoor veilig of ik spoor niet.


  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 09-09 20:58

Janoz

Moderator Devschuur®

!litemod

Wat lukt je niet? Het lijkt me redelijk triviaal om een C of vb algoritme om te zetten in php toch?

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • Anders
  • Registratie: December 2000
  • Laatst online: 24-08 18:29
Leek mij ook, maar gelukkig leek het niet aan mij te liggen: het bleek dat vrijwel elk stuk code dat ik hierover tegenkwam, barstensvol met fouten zat.

Voor de liefhebbers, mijn uiteindelijke versie:
PHP:
1
<?function RGB ($q1, $q2, $hue) {    if ($hue>360) $hue = $hue-360;    if ($hue<0) $hue = $hue + 360;    if ($hue<60) {        $RGB = $q1+($q2-$q1)*$hue/60;    } elseif ($hue < 180) {        $RGB = $q2;    } elseif ($hue<240) {        $RGB = $q1+($q1+$q2)*(240-$hue)/60;    } else {        $RGB=$q1;    }    return $RGB;}function HLS_to_RGB($hue, $lightness, $saturation) {    if ($lightness <=0.5) {        $p2 = $lightness * (1+$saturation);    } else {        $p2 = $lightness + $saturation - ($lightness*$saturation);    }    $p1 = 2 * $lightness - $p2;    if ($saturation == 0) {        $R = $lightness;        $G = $lightness;        $B = $lightness;    } else {        $R = RGB($p1, $p2, $hue+120);        $G = RGB($p1, $p2, $hue);        $B = RGB($p1, $p2, $hue-120);    }    $R = $R*255;    $G = $G*255;    $B = $B*255;    $returnarray[r] = dechex(round($R));    $returnarray[g] = dechex(round($G));    $returnarray[b] = dechex(round($B));    return $returnarray;}function RGB_to_HLS($color){    if (strstr($color, "#")) $color = substr($color, 1);    /* get R, G, and B out of DWORD */    $R = hexdec(substr($color,0,2));    $G = hexdec(substr($color,2,2));    $B = hexdec(substr($color,4,2));    $R = $R/255;    $G = $G/255;    $B = $B/255;    $max = max($R,$G,$B);    $min = min($R,$G,$B);            // LIGHTNESS    $lightness = ($max+$min)/2;    // SATURATION    if ($max == $min) {        // grayscale, geen hue, geen saturation        $saturation = 0;        $hue = false;    } else {        // kleur                // bereken eerst saturation        if ($lightness<0.5) {            $saturation = ($max-$min)/($max+$min);        } else {            $saturation = ($max-$min)/(2-$max-$min);        }        // Bereken nu de hue        $delta = $max-$min;        if ($max == $R) {        // rood de sterkste kleur            $hue = ($G-$B)/$delta;        } elseif ($max == $G) { // groen de sterkste kleur            $hue = 2 + ($B-$R)/$delta;        } elseif ($max == $B) { // blauw de sterkste kleur            $hue = 4 + ($R-$G)/$delta;        }        // reken hue om naar graden        $hue = $hue*60;        if ($hue<0.0) $hue = $hue + 360;    } // einde kleur    $returnarray[hue] = $hue;    $returnarray[lightness] = $lightness;    $returnarray[saturation] = $saturation;    return $returnarray;} // einde RGB_to_HSL$color = "#3399FF";$myhls = RGB_to_HLS($color);$myrgb = HLS_to_RGB($myhls[hue], $myhls[lightness], $myhls[saturation]);echo <<< eindHTML<B>Uitgangskleur:</B><UL><LI>$color</UL><P><B>RGB to HSL:</B><UL>    <LI>Hue = $myhls[hue]    <LI>Lightness = $myhls[lightness]    <LI>Saturation = $myhls[saturation]</UL><P><B>RGB to HSL:</B><UL>    <LI>R = $myrgb[r]    <LI>G = $myrgb[g]    <LI>B = $myrgb[b]</UL>eindHTML;?>

Ik spoor veilig of ik spoor niet.


  • SuperRembo
  • Registratie: Juni 2000
  • Laatst online: 20-08-2025
Ik had geen zin om te zoeken naar de fout in jouw script, dus heb ik 'm opnieuw gemaakt (ook op basis van een stukje C). Alle r,g,b en h,l,s waarden liggen tussen 0 en 1.
PHP:
1
<?    function HLStoRGB ($h, $l, $s) {        if ( $s == 0 ) {            // achromatic (grey)            $r = $g = $b = $l;        } else {            $sector = floor( 6 * $h );            $f = 6*$h - $sector;            $m = $l;            $p = $l * ( 1 - $s);            $q = $l * ( 1 - $s * $f );            $t = $l * ( 1 - $s * ( 1 - $f ) );            switch( $sector ) {                case 0:                    $r = $m;                    $g = $t;                    $b = $p;                    break;                case 1:                    $r = $q;                    $g = $m;                    $b = $p;                    break;                case 2:                    $r = $p;                    $g = $m;                    $b = $t;                    break;                case 3:                    $r = $p;                    $g = $q;                    $b = $m;                    break;                case 4:                    $r = $t;                    $g = $p;                    $b = $m;                    break;                default:        // case 5:                    $r = $m;                    $g = $p;                    $b = $q;                    break;            }        }        return array($r, $g, $b);    } // einde RGBtoHLS    function RGBtoHLS ($r, $g, $b) {        $min = min( $r, $g, $b );        $max = max( $r, $g, $b );        if( $max == 0 ) {            // zwart -> hue en sat ongedefinieerd            $h = 0;            $l = 0;            $s = 0;        } else {            $delta = $max - $min;            // luminance            $l = $max;            // saturation            $s = $delta;            // hue            if( $r == $max )                $h = ( $g - $b ) / $delta;        // between yellow &amp; magenta            elseif( $g == $max )                $h = 2 + ( $b - $r ) / $delta;    // between cyan &amp; yellow            else                $h = 4 + ( $r - $g ) / $delta;    // between magenta &amp; cyan            $h = $h / 6;            if( $h < 0 )                $h++;        }        return array($h, $l, $s);    } // einde RGBtoHSL    function getRGB($color) {        if (strstr($color, "#"))            $color = substr($color, 1);        $r = hexdec(substr($color,0,2))/255;        $g = hexdec(substr($color,2,2))/255;        $b = hexdec(substr($color,4,2))/255;        return array($r, $g, $b);    }    function RGBstr($r, $g, $b) {        $r = str_pad(dechex(255*$r), 2, '0', STR_PAD_LEFT);        $g = str_pad(dechex(255*$g), 2, '0', STR_PAD_LEFT);        $b = str_pad(dechex(255*$b), 2, '0', STR_PAD_LEFT);        return "#$r$g$b";    }    $mycolor = "#f011ff";    list($r, $g, $b) = getRGB($mycolor);    list($h, $l, $s) = RGBtoHLS($r, $g, $b);    list($r2, $g2, $b2) = HLStoRGB($h, $l, $s);    $mycolor2 = RGBstr($r2, $g2, $b2);    echo "<b>Uitgangskleur:</b> $mycolor ($r, $g, $b)        <div style=\"width:20px;height:20px;background-color:$mycolor\"></div>        <p>        <b>RGB to HLS:</b> ($h, $l, $s)        <p>        <b>HLS to RGB:</b> ($r2, $g2, $b2)        <div style=\"width:20px;height:20px;background-color:{$mycolor2}\"></div>        ";?>

| Toen / Nu


  • Anders
  • Registratie: December 2000
  • Laatst online: 24-08 18:29
Thanks a lot voor de moeite, SuperRambo, maar ik geloof dat ik er bij had moeten schrijven dat mijn uiteindelijke versie wel werkt :)

Ik spoor veilig of ik spoor niet.