Color.php 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. <?php
  2. namespace Drupal\Component\Utility;
  3. /**
  4. * Performs color conversions.
  5. */
  6. class Color {
  7. /**
  8. * Validates whether a hexadecimal color value is syntactically correct.
  9. *
  10. * @param $hex
  11. * The hexadecimal string to validate. May contain a leading '#'. May use
  12. * the shorthand notation (e.g., '123' for '112233').
  13. *
  14. * @return bool
  15. * TRUE if $hex is valid or FALSE if it is not.
  16. */
  17. public static function validateHex($hex) {
  18. // Must be a string.
  19. $valid = is_string($hex);
  20. // Hash prefix is optional.
  21. $hex = ltrim($hex, '#');
  22. // Must be either RGB or RRGGBB.
  23. $length = mb_strlen($hex);
  24. $valid = $valid && ($length === 3 || $length === 6);
  25. // Must be a valid hex value.
  26. $valid = $valid && ctype_xdigit($hex);
  27. return $valid;
  28. }
  29. /**
  30. * Parses a hexadecimal color string like '#abc' or '#aabbcc'.
  31. *
  32. * @param string $hex
  33. * The hexadecimal color string to parse.
  34. *
  35. * @return array
  36. * An array containing the values for 'red', 'green', 'blue'.
  37. *
  38. * @throws \InvalidArgumentException
  39. */
  40. public static function hexToRgb($hex) {
  41. if (!self::validateHex($hex)) {
  42. throw new \InvalidArgumentException("'$hex' is not a valid hex value.");
  43. }
  44. // Ignore '#' prefixes.
  45. $hex = ltrim($hex, '#');
  46. // Convert shorthands like '#abc' to '#aabbcc'.
  47. if (strlen($hex) == 3) {
  48. $hex = $hex[0] . $hex[0] . $hex[1] . $hex[1] . $hex[2] . $hex[2];
  49. }
  50. $c = hexdec($hex);
  51. return [
  52. 'red' => $c >> 16 & 0xFF,
  53. 'green' => $c >> 8 & 0xFF,
  54. 'blue' => $c & 0xFF,
  55. ];
  56. }
  57. /**
  58. * Converts RGB color arrays and RGB strings in CSS notation to lowercase
  59. * simple colors like '#aabbcc'.
  60. *
  61. * @param array|string $input
  62. * The value to convert. If the value is an array the first three elements
  63. * will be used as the red, green and blue components. String values in CSS
  64. * notation like '10, 20, 30' are also supported.
  65. *
  66. * @return string
  67. * The lowercase simple color representation of the given color.
  68. */
  69. public static function rgbToHex($input) {
  70. // Remove named array keys if input comes from Color::hex2rgb().
  71. if (is_array($input)) {
  72. $rgb = array_values($input);
  73. }
  74. // Parse string input in CSS notation ('10, 20, 30').
  75. elseif (is_string($input)) {
  76. preg_match('/(\d+), ?(\d+), ?(\d+)/', $input, $rgb);
  77. array_shift($rgb);
  78. }
  79. $out = 0;
  80. foreach ($rgb as $k => $v) {
  81. $out |= $v << (16 - $k * 8);
  82. }
  83. return '#' . str_pad(dechex($out), 6, 0, STR_PAD_LEFT);
  84. }
  85. /**
  86. * Normalize the hex color length to 6 characters for comparison.
  87. *
  88. * @param string $hex
  89. * The hex color to normalize.
  90. *
  91. * @return string
  92. * The 6 character hex color.
  93. */
  94. public static function normalizeHexLength($hex) {
  95. // Ignore '#' prefixes.
  96. $hex = ltrim($hex, '#');
  97. if (strlen($hex) === 3) {
  98. $hex[5] = $hex[2];
  99. $hex[4] = $hex[2];
  100. $hex[3] = $hex[1];
  101. $hex[2] = $hex[1];
  102. $hex[1] = $hex[0];
  103. }
  104. return '#' . $hex;
  105. }
  106. }