AbstractColor.php 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. <?php
  2. namespace Intervention\Image;
  3. use Intervention\Image\Exception\NotReadableException;
  4. use Intervention\Image\Exception\NotSupportedException;
  5. abstract class AbstractColor
  6. {
  7. /**
  8. * Initiates color object from integer
  9. *
  10. * @param int $value
  11. * @return \Intervention\Image\AbstractColor
  12. */
  13. abstract public function initFromInteger($value);
  14. /**
  15. * Initiates color object from given array
  16. *
  17. * @param array $value
  18. * @return \Intervention\Image\AbstractColor
  19. */
  20. abstract public function initFromArray($value);
  21. /**
  22. * Initiates color object from given string
  23. *
  24. * @param string $value
  25. * @return \Intervention\Image\AbstractColor
  26. */
  27. abstract public function initFromString($value);
  28. /**
  29. * Initiates color object from given ImagickPixel object
  30. *
  31. * @param ImagickPixel $value
  32. * @return \Intervention\Image\AbstractColor
  33. */
  34. abstract public function initFromObject($value);
  35. /**
  36. * Initiates color object from given R, G and B values
  37. *
  38. * @param int $r
  39. * @param int $g
  40. * @param int $b
  41. * @return \Intervention\Image\AbstractColor
  42. */
  43. abstract public function initFromRgb($r, $g, $b);
  44. /**
  45. * Initiates color object from given R, G, B and A values
  46. *
  47. * @param int $r
  48. * @param int $g
  49. * @param int $b
  50. * @param float $a
  51. * @return \Intervention\Image\AbstractColor
  52. */
  53. abstract public function initFromRgba($r, $g, $b, $a);
  54. /**
  55. * Calculates integer value of current color instance
  56. *
  57. * @return int
  58. */
  59. abstract public function getInt();
  60. /**
  61. * Calculates hexadecimal value of current color instance
  62. *
  63. * @param string $prefix
  64. * @return string
  65. */
  66. abstract public function getHex($prefix);
  67. /**
  68. * Calculates RGB(A) in array format of current color instance
  69. *
  70. * @return array
  71. */
  72. abstract public function getArray();
  73. /**
  74. * Calculates RGBA in string format of current color instance
  75. *
  76. * @return string
  77. */
  78. abstract public function getRgba();
  79. /**
  80. * Determines if current color is different from given color
  81. *
  82. * @param AbstractColor $color
  83. * @param int $tolerance
  84. * @return boolean
  85. */
  86. abstract public function differs(AbstractColor $color, $tolerance = 0);
  87. /**
  88. * Creates new instance
  89. *
  90. * @param mixed $value
  91. */
  92. public function __construct($value = null)
  93. {
  94. $this->parse($value);
  95. }
  96. /**
  97. * Parses given value as color
  98. *
  99. * @param mixed $value
  100. * @return \Intervention\Image\AbstractColor
  101. */
  102. public function parse($value)
  103. {
  104. switch (true) {
  105. case is_string($value):
  106. $this->initFromString($value);
  107. break;
  108. case is_int($value):
  109. $this->initFromInteger($value);
  110. break;
  111. case is_array($value):
  112. $this->initFromArray($value);
  113. break;
  114. case is_object($value):
  115. $this->initFromObject($value);
  116. break;
  117. case is_null($value):
  118. $this->initFromArray([255, 255, 255, 0]);
  119. break;
  120. default:
  121. throw new NotReadableException(
  122. "Color format ({$value}) cannot be read."
  123. );
  124. }
  125. return $this;
  126. }
  127. /**
  128. * Formats current color instance into given format
  129. *
  130. * @param string $type
  131. * @return mixed
  132. */
  133. public function format($type)
  134. {
  135. switch (strtolower($type)) {
  136. case 'rgba':
  137. return $this->getRgba();
  138. case 'hex':
  139. return $this->getHex('#');
  140. case 'int':
  141. case 'integer':
  142. return $this->getInt();
  143. case 'array':
  144. return $this->getArray();
  145. case 'obj':
  146. case 'object':
  147. return $this;
  148. default:
  149. throw new NotSupportedException(
  150. "Color format ({$type}) is not supported."
  151. );
  152. }
  153. }
  154. /**
  155. * Reads RGBA values from string into array
  156. *
  157. * @param string $value
  158. * @return array
  159. */
  160. protected function rgbaFromString($value)
  161. {
  162. $result = false;
  163. // parse color string in hexidecimal format like #cccccc or cccccc or ccc
  164. $hexPattern = '/^#?([a-f0-9]{1,2})([a-f0-9]{1,2})([a-f0-9]{1,2})$/i';
  165. // parse color string in format rgb(140, 140, 140)
  166. $rgbPattern = '/^rgb ?\(([0-9]{1,3}), ?([0-9]{1,3}), ?([0-9]{1,3})\)$/i';
  167. // parse color string in format rgba(255, 0, 0, 0.5)
  168. $rgbaPattern = '/^rgba ?\(([0-9]{1,3}), ?([0-9]{1,3}), ?([0-9]{1,3}), ?([0-9.]{1,4})\)$/i';
  169. if (preg_match($hexPattern, $value, $matches)) {
  170. $result = [];
  171. $result[0] = strlen($matches[1]) == '1' ? hexdec($matches[1].$matches[1]) : hexdec($matches[1]);
  172. $result[1] = strlen($matches[2]) == '1' ? hexdec($matches[2].$matches[2]) : hexdec($matches[2]);
  173. $result[2] = strlen($matches[3]) == '1' ? hexdec($matches[3].$matches[3]) : hexdec($matches[3]);
  174. $result[3] = 1;
  175. } elseif (preg_match($rgbPattern, $value, $matches)) {
  176. $result = [];
  177. $result[0] = ($matches[1] >= 0 && $matches[1] <= 255) ? intval($matches[1]) : 0;
  178. $result[1] = ($matches[2] >= 0 && $matches[2] <= 255) ? intval($matches[2]) : 0;
  179. $result[2] = ($matches[3] >= 0 && $matches[3] <= 255) ? intval($matches[3]) : 0;
  180. $result[3] = 1;
  181. } elseif (preg_match($rgbaPattern, $value, $matches)) {
  182. $result = [];
  183. $result[0] = ($matches[1] >= 0 && $matches[1] <= 255) ? intval($matches[1]) : 0;
  184. $result[1] = ($matches[2] >= 0 && $matches[2] <= 255) ? intval($matches[2]) : 0;
  185. $result[2] = ($matches[3] >= 0 && $matches[3] <= 255) ? intval($matches[3]) : 0;
  186. $result[3] = ($matches[4] >= 0 && $matches[4] <= 1) ? $matches[4] : 0;
  187. } else {
  188. throw new NotReadableException(
  189. "Unable to read color ({$value})."
  190. );
  191. }
  192. return $result;
  193. }
  194. }