I have a hex value of some color, for example #202010.
How to generate a new color which is either lighter or darker given in percent (ie. 20% darker) in PHP?
I have a hex value of some color, for example #202010.
How to generate a new color which is either lighter or darker given in percent (ie. 20% darker) in PHP?
Torkil Johnsen's answer is based on fixed step which doesn't manipulate only brightness but also slightly changes the hue. Frxstrem's method has flaws too as Torkil Johnsen noted.
I've taken this approach from a Github comment and improved the code. It works perfectly for any case.
/**
* Increases or decreases the brightness of a color by a percentage of the current brightness.
*
* @param string $hexCode Supported formats: `#FFF`, `#FFFFFF`, `FFF`, `FFFFFF`
* @param float $adjustPercent A number between -1 and 1. E.g. 0.3 = 30% lighter; -0.4 = 40% darker.
*
* @return string
*
* @author maliayas
*/
function adjustBrightness($hexCode, $adjustPercent) {
$hexCode = ltrim($hexCode, '#');
if (strlen($hexCode) == 3) {
$hexCode = $hexCode[0] . $hexCode[0] . $hexCode[1] . $hexCode[1] . $hexCode[2] . $hexCode[2];
}
$hexCode = array_map('hexdec', str_split($hexCode, 2));
foreach ($hexCode as & $color) {
$adjustableLimit = $adjustPercent < 0 ? $color : 255 - $color;
$adjustAmount = ceil($adjustableLimit * $adjustPercent);
$color = str_pad(dechex($color + $adjustAmount), 2, '0', STR_PAD_LEFT);
}
return '#' . implode($hexCode);
}
Here is an example result:
If you want a simple implementation and you don't care that much about the values being specifically above 50% lightness (or whatever your threshold), you can use my solution for lighter colors:
$color = sprintf('#%06X', mt_rand(0xFFFFFF / 1.5, 0xFFFFFF));
The idea is to generate a random color in the higher part of the palette. You can adjust the results to be more or less dark by changing the "1.5" value:
You can do the same for darker colors by setting the starting point of the random function to "0x000000" and dividing the end limit:
$color = sprintf('#%06X', mt_rand(0x000000, 0xFFFFFF / 1.5));
I know this is not a precise but it works for me.