Created
May 28, 2019 08:34
-
-
Save teknikqa/231b65be6877d80bd0ca02cd42295cca to your computer and use it in GitHub Desktop.
Find the appropriate color that works best on a given background color.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* @file | |
* Find the appropriate color that works best on a given background color. | |
*/ | |
/** | |
* Convert the standard RGB color to linear RGB. | |
* | |
* Returns a linear color based on the formula mentioned in | |
* https://www.w3.org/TR/WCAG20/#relativeluminancedef. | |
*/ | |
function convert_standard_color_to_linear($color) { | |
if ($color <= 0.03928) { | |
return $color / 12.92; | |
} | |
else { | |
return pow(($color + 0.055) / 1.055, 2.4); | |
} | |
} | |
/** | |
* Convert a HEX value to RGB. | |
* | |
* @param string $hexStr | |
* The hex value to convert. | |
* @param bool $returnAsString | |
* Whether to return this as a string. | |
* @param string $seperator | |
* The character that will be used to separate the values. | |
* | |
* @return string | |
* The converted value in RGB. | |
*/ | |
function hex2_rgb($hexStr, $returnAsString = FALSE, $seperator = ',') { | |
// Gets a proper hex string. | |
$hexStr = preg_replace("/[^0-9A-Fa-f]/", '', $hexStr); | |
$rgbArray = array(); | |
if (strlen($hexStr) == 6) { | |
// If a proper hex code, convert using bitwise operation. No overhead and is | |
// faster. | |
$colorVal = hexdec($hexStr); | |
$rgbArray['red'] = 0xFF & ($colorVal >> 0x10); | |
$rgbArray['green'] = 0xFF & ($colorVal >> 0x8); | |
$rgbArray['blue'] = 0xFF & $colorVal; | |
} | |
elseif (strlen($hexStr) == 3) { | |
// If shorthand notation, need some string manipulations. | |
$rgbArray['red'] = hexdec(str_repeat(substr($hexStr, 0, 1), 2)); | |
$rgbArray['green'] = hexdec(str_repeat(substr($hexStr, 1, 1), 2)); | |
$rgbArray['blue'] = hexdec(str_repeat(substr($hexStr, 2, 1), 2)); | |
} | |
else { | |
// Invalid hex color code. | |
return FALSE; | |
} | |
return $returnAsString ? implode($seperator, $rgbArray) : $rgbArray; | |
} | |
/** | |
* Calculate the inverse color given a hex value. | |
* | |
* @param string $hex | |
* The hex value to invert. | |
* @param bool $bw | |
* Whether to invert to only black or white. | |
* @param bool $strict | |
* Set this to TRUE to find colors that match W3C guidelines. | |
* | |
* @return bool|string | |
* Reurns FALSE if invalid hex code, else returns the inverted color in RGB. | |
*/ | |
function invert_color($hex, $bw = FALSE, $strict = FALSE) { | |
// Gets a proper hex string. | |
$hex = preg_replace("/[^0-9A-Fa-f]/", '', $hex); | |
if ($hex[0] == '#') { | |
$hex = substr($hex, 1); | |
} | |
// If this is a proper hex code, convert using bitwise operation. This has no | |
// overhead and is faster. | |
if (strlen($hex) == 6) { | |
$hex = hexdec($hex); | |
$r = 0xFF & ($hex >> 0x10); | |
$g = 0xFF & ($hex >> 0x8); | |
$b = 0xFF & $hex; | |
} | |
// If the value is in shorthand notation, we need to do some string | |
// manipulations. | |
elseif (strlen($hex) == 3) { | |
$r = hexdec(str_repeat(substr($hexStr, 0, 1), 2)); | |
$g = hexdec(str_repeat(substr($hexStr, 1, 1), 2)); | |
$b = hexdec(str_repeat(substr($hexStr, 2, 1), 2)); | |
} | |
// Invalid hex color code. | |
else { | |
return FALSE; | |
} | |
// If $strict is set, then the inverted colors will be black or white. | |
if ($strict == TRUE) { | |
// Based on the answer provided in this StackOverflow question | |
// https://stackoverflow.com/a/3943023/112731 | |
$sRGB = [$r / 255, $g / 255, $b / 255]; | |
$lRGB = array_map("convert_standard_color_to_linear", $sRGB); | |
$luminosity = 0.2126 * $lRGB[0] + 0.7152 * $lRGB[1] + 0.0722 * $lRGB[2]; | |
// $intensity should be > 186; | |
return ($luminosity > 0.179) | |
? '#000000' | |
: '#FFFFFF'; | |
} | |
if ($bw == TRUE) { | |
// Based on the answer provided in this StackOverflow question | |
// https://stackoverflow.com/a/3943023/112731 | |
$intensity = $r * 0.299 + $g * 0.587 + $b * 0.114; | |
// $intensity should be > 186; | |
return ($intensity > 186) | |
? '#000000' | |
: '#FFFFFF'; | |
} | |
// Invert color components. | |
$r = (string) dechex((float) 255 - $r); | |
$g = (string) dechex((float) 255 - $g); | |
$b = (string) dechex((float) 255 - $b); | |
// Pad each value with leading zeros if required. | |
$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); | |
return "#" . $r . $g . $b; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment