4

Imagine a valid #RGB color in hexadecimal, defined as $color = "#f7b9a0";

Now I want to have php derive from this $color two other colors which are slightly lighter/darker (same hue/color but just altered brightness). What ways could I achieve this? What code will generate this? I have the feeling I need something simple like:

brightness(input rgb color, ± number of steps); // function outputs the new RGB
 // ?? What php code should go here??

Ideally, I wish to have something like this in my html:

.classDefault {color:<?=$color?> }
.classLighter {color:<?=brightness($color,+10)?> } /* 10 steps brighter */
.classDarker  {color:<?=brightness($color,-25)?> } /* 25 steps darker   */

What PHP code should go in the brightness(); function? for my dream to come true?
Any suggestions and or code are both very appreciated!


updated from the answer below:

function alter_brightness($colourstr, $steps) {
  $colourstr = str_replace('#','',$colourstr);
  $rhex = substr($colourstr,0,2);
  $ghex = substr($colourstr,2,2);
  $bhex = substr($colourstr,4,2);

  $r = hexdec($rhex);
  $g = hexdec($ghex);
  $b = hexdec($bhex);

  $r = max(0,min(255,$r + $steps));
  $g = max(0,min(255,$g + $steps));  
  $b = max(0,min(255,$b + $steps));

  return '#'.dechex($r).dechex($g).dechex($b);
}

### NOW LETS DEFINE MY COLOR
$color = "#2233FF";

### DERIVED BRIGHTER COLORS
$color1 = brightness($color,25);
$color2 = brightness($color,50);
$color3 = brightness($color,75);

### DERIVED DARKER COLORS
$color4 = brightness($color,-25);
$color5 = brightness($color,-50);
$color6 = brightness($color,-75);


<!-- BRIGHTER -->
<div style=" background-color:<?=$color3?>"><?=$color3?></div>
<div style=" background-color:<?=$color2?>"><?=$color2?></div>
<div style=" background-color:<?=$color1?>"><?=$color1?></div>

<!-- DEFINED CONSTANT -->
<div style=" background-color:<?=$color?>"><?=$color?></div>

<!-- DARKER -->
<div style=" background-color:<?=$color4?>"><?=$color4?></div>
<div style=" background-color:<?=$color5?>"><?=$color5?></div>
<div style=" background-color:<?=$color6?>"><?=$color6?></div>

the brighter colors work, but the darker not. Oh well half solution is at least big part of solution so Thanks very much!

Community
  • 1
  • 1
Sam
  • 15,254
  • 25
  • 90
  • 145
  • 3
    Possibly useful info: [Darken or lighten colours dynamically using PHP](http://lab.clearpixel.com.au/2008/06/darken-or-lighten-colours-dynamically-using-php/) / [How to Calculate a Complementary Colour](http://www.serennu.com/colour/rgbtohsl.php) – drudge Mar 04 '11 at 22:02
  • @ jnpcl, wwwoooops what happened to the other link you placed, found that interesting too, i suppose – Sam Mar 04 '11 at 22:05
  • I found a new one that seemed to be a better fit for your solution. :) I'll add it back~ – drudge Mar 04 '11 at 22:06

5 Answers5

7

Something along these lines...

function alter_brightness($colourstr, $steps) {
  $colourstr = str_replace('#','',$colourstr);
  $rhex = substr($colourstr,0,2);
  $ghex = substr($colourstr,2,2);
  $bhex = substr($colourstr,4,2);

  $r = hexdec($rhex);
  $g = hexdec($ghex);
  $b = hexdec($bhex);

  $r = max(0,min(255,$r + $steps));
  $g = max(0,min(255,$g + $steps));  
  $b = max(0,min(255,$b + $steps));

  return '#'.dechex($r).dechex($g).dechex($b);
}

Call like $colour = alter_brightness('#2233FF',5);

brenjt
  • 15,997
  • 13
  • 77
  • 118
cusimar9
  • 5,185
  • 4
  • 24
  • 30
  • 1
    Surely you meant to use a period instead of plus sign for putting the string together. – Kevin Peno Mar 04 '11 at 22:20
  • +1 Thanks very much @Cusimar9 and @Kevin, when i run the code it says `Fatal error: Call to undefined function hecdec() in /var/www/vhosts/aster.nu/httpdocs/color.php on line 148` I see in the code hecdec() as well as hecdex() what should be done here? I like very much your final line: the way to call the function is what IU had in mind. This is going to be one nice solution... when it works :) – Sam Mar 04 '11 at 23:29
  • solved! hexdec / decdex were misspelled in your code, but it works beautifully for making colors brighter, hoewever, how can I make them darker? when i make the variable "-5" or any other minus value, then I get incorrect RGB numers! See my update – Sam Mar 04 '11 at 23:58
  • When you say the 'darker' colours don't work, what result does it actually give you, for -25 for example? – cusimar9 Mar 05 '11 at 08:53
  • 1
    replace return line with this one : return sprintf("#%02x%02x%02x", $r,$g,$b); – Julien Apr 20 '13 at 17:57
5

Cintia is almost right, but the str_pad should add a 0 before not after:

<?php 

function alter_brightness($colourstr, $steps) {
  $colourstr = str_replace('#','',$colourstr);

  $rhex = substr($colourstr,0,2);
  $ghex = substr($colourstr,2,2);
  $bhex = substr($colourstr,4,2);

  $r = hexdec($rhex);
  $g = hexdec($ghex);
  $b = hexdec($bhex);

  $r = dechex(max(0,min(255,$r + $steps)));
  $g = dechex(max(0,min(255,$g + $steps)));  
  $b = dechex(max(0,min(255,$b + $steps)));

  $r = str_pad($r,2,"0",STR_PAD_LEFT);
  $g = str_pad($g,2,"0",STR_PAD_LEFT);
  $b = str_pad($b,2,"0",STR_PAD_LEFT);

  $cor = '#'.$r.$g.$b;

  return $cor;
}

?>
Azzoth
  • 53
  • 1
  • 5
2

Use the second answer. or add the following to your code:

If the rgb value is 10 or so, it will return single character for hex. It needs to be prefixed with 0 to render properly.

  $newhex = '#';
  $newhex .= (strlen(dechex($r)) === 1) ?  '0'.dechex($r) : dechex($r);
  $newhex .= (strlen(dechex($g)) === 1) ?  '0'.dechex($g) : dechex($g);
  $newhex .= (strlen(dechex($b)) === 1) ?  '0'.dechex($b) : dechex($b);

  return $newhex;
dandan
  • 1,016
  • 8
  • 16
2
<?php 

function alter_brightness($colourstr, $steps) {
  $colourstr = str_replace('#','',$colourstr);

  $rhex = substr($colourstr,0,2);
  $ghex = substr($colourstr,2,2);
  $bhex = substr($colourstr,4,2);

  $r = hexdec($rhex);
  $g = hexdec($ghex);
  $b = hexdec($bhex);

  $r = dechex(max(0,min(255,$r + $steps)));
  $g = dechex(max(0,min(255,$g + $steps)));  
  $b = dechex(max(0,min(255,$b + $steps)));

  $r = str_pad($r,2,"0");
  $g = str_pad($g,2,"0");
  $b = str_pad($b,2,"0");

  $cor = '#'.$r.$g.$b;

  return $cor;
}

?>
Cintia
  • 29
  • 1
0

Here is the minified version of the function. I used str_pad to add the 0 for the numbers < 10. The version of cusimar9 doesn't check that.

 function alter_brightness($colourstr, $steps) {
    //Take off the #
    $colourstr    = str_replace( '#', '', $colourstr );
    // Steps should be between -255 and 255. Negative = darker, positive = lighter
    $steps  = max( -255, min( 255, $steps ) );
    // Transform colors of type #fff to #ffffff
    if ( 3 == strlen( $colourstr ) ) {
        $colourstr    = str_repeat( substr( $colourstr, 0, 1 ), 2 ) . str_repeat( substr( $colourstr, 1, 1 ), 2 ) . str_repeat( substr( $colourstr, 2, 1 ), 2 );
    }
    // Modify the brigthness of each component
    $rgb=array(substr($colourstr,0,2),  substr($colourstr,2,2), substr($colourstr,4,2));
    for($i = 0; $i< count($rgb); $i++){
      $rgb[$i] = str_pad(dechex(max(0,min(255, hexdec($rgb[$i]) + $steps))),2,"0",STR_PAD_LEFT) ;
    }
    return '#'.implode('', $rgb);
}
Jack Wire
  • 681
  • 12
  • 25