Skip to content

Instantly share code, notes, and snippets.

@stephenharris
Created May 7, 2013 14:19
Show Gist options
  • Save stephenharris/5532899 to your computer and use it in GitHub Desktop.
Save stephenharris/5532899 to your computer and use it in GitHub Desktop.
Lighten or darken a given colour
<?php
/**
* Lightens/darkens a given colour (hex format), returning the altered colour in hex format.7
* @param str $hex Colour as hexadecimal (with or without hash);
* @percent float $percent Decimal ( 0.2 = lighten by 20%(), -0.4 = darken by 40%() )
* @return str Lightened/Darkend colour as hexadecimal (with hash);
*/
function color_luminance( $hex, $percent ) {
// validate hex string
$hex = preg_replace( '/[^0-9a-f]/i', '', $hex );
$new_hex = '#';
if ( strlen( $hex ) < 6 ) {
$hex = $hex[0] + $hex[0] + $hex[1] + $hex[1] + $hex[2] + $hex[2];
}
// convert to decimal and change luminosity
for ($i = 0; $i < 3; $i++) {
$dec = hexdec( substr( $hex, $i*2, 2 ) );
$dec = min( max( 0, $dec + $dec * $percent ), 255 );
$new_hex .= str_pad( dechex( $dec ) , 2, 0, STR_PAD_LEFT );
}
return $new_hex;
}
@regularlabs
Copy link

regularlabs commented Sep 16, 2017

This is a different approach.
It expects and returns an array of the rbg color values, like array(0, 100, 255).
But you can of course create your own simple decimal to hex converter in there.

	// 0% =  black
	// 50% = no change
	// 100% = white
	function luminate($color, $percent)
	{
		foreach ($color as &$value)
		{
			$value = min(max(0, self::luminateValue($value, $percent)), 255);
		}

		return $color;
	}

	function luminateValue($value, $percent)
	{
		// no change
		if ($percent == 50)
		{
			return $value;
		}

		// ratio = value from 0 to 2
		$ratio = $percent * 2 / 100;

		// darken color
		if ($percent < 50)
		{
			return $value * $ratio;
		}

		// lighten color

		// reverse ratio
		$ratio = 2 - $ratio;

		$diff  = (255 - $value) * $ratio;

		return 255 - $diff;
	}

@jeanchernandez
Copy link

This works for me:

function luminance($hexcolor, $percent)
{
  if ( strlen( $hexcolor ) < 6 ) {
    $hexcolor = $hexcolor[0] . $hexcolor[0] . $hexcolor[1] . $hexcolor[1] . $hexcolor[2] . $hexcolor[2];
  }
  $hexcolor = array_map('hexdec', str_split( str_pad( str_replace('#', '', $hexcolor), 6, '0' ), 2 ) );

  foreach ($hexcolor as $i => $color) {
    $from = $percent < 0 ? 0 : $color;
    $to = $percent < 0 ? $color : 255;
    $pvalue = ceil( ($to - $from) * $percent );
    $hexcolor[$i] = str_pad( dechex($color + $pvalue), 2, '0', STR_PAD_LEFT);
  }

  return '#' . implode($hexcolor);
}

@theus
Copy link

theus commented Mar 19, 2018

Oh, great. Thank you.

@papac
Copy link

papac commented Jul 20, 2018

Thank you

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment