How to generate lighter/darker color with PHP?

Viewed 49558

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?

7 Answers

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:

example

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:

  • larger will expand the palette into darker colors
  • smaller will curb it to lighter colors

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.

Related