1<?php 2 3namespace Intervention\Image\Gd; 4 5use Intervention\Image\AbstractColor; 6use Intervention\Image\Exception\NotSupportedException; 7 8class Color extends AbstractColor 9{ 10 /** 11 * RGB Red value of current color instance 12 * 13 * @var int 14 */ 15 public $r; 16 17 /** 18 * RGB Green value of current color instance 19 * 20 * @var int 21 */ 22 public $g; 23 24 /** 25 * RGB Blue value of current color instance 26 * 27 * @var int 28 */ 29 public $b; 30 31 /** 32 * RGB Alpha value of current color instance 33 * 34 * @var float 35 */ 36 public $a; 37 38 /** 39 * Initiates color object from integer 40 * 41 * @param int $value 42 * @return \Intervention\Image\AbstractColor 43 */ 44 public function initFromInteger($value) 45 { 46 $this->a = ($value >> 24) & 0xFF; 47 $this->r = ($value >> 16) & 0xFF; 48 $this->g = ($value >> 8) & 0xFF; 49 $this->b = $value & 0xFF; 50 } 51 52 /** 53 * Initiates color object from given array 54 * 55 * @param array $value 56 * @return \Intervention\Image\AbstractColor 57 */ 58 public function initFromArray($array) 59 { 60 $array = array_values($array); 61 62 if (count($array) == 4) { 63 64 // color array with alpha value 65 list($r, $g, $b, $a) = $array; 66 $this->a = $this->alpha2gd($a); 67 68 } elseif (count($array) == 3) { 69 70 // color array without alpha value 71 list($r, $g, $b) = $array; 72 $this->a = 0; 73 74 } 75 76 $this->r = $r; 77 $this->g = $g; 78 $this->b = $b; 79 } 80 81 /** 82 * Initiates color object from given string 83 * 84 * @param string $value 85 * @return \Intervention\Image\AbstractColor 86 */ 87 public function initFromString($value) 88 { 89 if ($color = $this->rgbaFromString($value)) { 90 $this->r = $color[0]; 91 $this->g = $color[1]; 92 $this->b = $color[2]; 93 $this->a = $this->alpha2gd($color[3]); 94 } 95 } 96 97 /** 98 * Initiates color object from given R, G and B values 99 * 100 * @param int $r 101 * @param int $g 102 * @param int $b 103 * @return \Intervention\Image\AbstractColor 104 */ 105 public function initFromRgb($r, $g, $b) 106 { 107 $this->r = intval($r); 108 $this->g = intval($g); 109 $this->b = intval($b); 110 $this->a = 0; 111 } 112 113 /** 114 * Initiates color object from given R, G, B and A values 115 * 116 * @param int $r 117 * @param int $g 118 * @param int $b 119 * @param float $a 120 * @return \Intervention\Image\AbstractColor 121 */ 122 public function initFromRgba($r, $g, $b, $a = 1) 123 { 124 $this->r = intval($r); 125 $this->g = intval($g); 126 $this->b = intval($b); 127 $this->a = $this->alpha2gd($a); 128 } 129 130 /** 131 * Initiates color object from given ImagickPixel object 132 * 133 * @param ImagickPixel $value 134 * @return \Intervention\Image\AbstractColor 135 */ 136 public function initFromObject($value) 137 { 138 throw new NotSupportedException( 139 "GD colors cannot init from ImagickPixel objects." 140 ); 141 } 142 143 /** 144 * Calculates integer value of current color instance 145 * 146 * @return int 147 */ 148 public function getInt() 149 { 150 return ($this->a << 24) + ($this->r << 16) + ($this->g << 8) + $this->b; 151 } 152 153 /** 154 * Calculates hexadecimal value of current color instance 155 * 156 * @param string $prefix 157 * @return string 158 */ 159 public function getHex($prefix = '') 160 { 161 return sprintf('%s%02x%02x%02x', $prefix, $this->r, $this->g, $this->b); 162 } 163 164 /** 165 * Calculates RGB(A) in array format of current color instance 166 * 167 * @return array 168 */ 169 public function getArray() 170 { 171 return [$this->r, $this->g, $this->b, round(1 - $this->a / 127, 2)]; 172 } 173 174 /** 175 * Calculates RGBA in string format of current color instance 176 * 177 * @return string 178 */ 179 public function getRgba() 180 { 181 return sprintf('rgba(%d, %d, %d, %.2F)', $this->r, $this->g, $this->b, round(1 - $this->a / 127, 2)); 182 } 183 184 /** 185 * Determines if current color is different from given color 186 * 187 * @param AbstractColor $color 188 * @param int $tolerance 189 * @return boolean 190 */ 191 public function differs(AbstractColor $color, $tolerance = 0) 192 { 193 $color_tolerance = round($tolerance * 2.55); 194 $alpha_tolerance = round($tolerance * 1.27); 195 196 $delta = [ 197 'r' => abs($color->r - $this->r), 198 'g' => abs($color->g - $this->g), 199 'b' => abs($color->b - $this->b), 200 'a' => abs($color->a - $this->a) 201 ]; 202 203 return ( 204 $delta['r'] > $color_tolerance or 205 $delta['g'] > $color_tolerance or 206 $delta['b'] > $color_tolerance or 207 $delta['a'] > $alpha_tolerance 208 ); 209 } 210 211 /** 212 * Convert rgba alpha (0-1) value to gd value (0-127) 213 * 214 * @param float $input 215 * @return int 216 */ 217 private function alpha2gd($input) 218 { 219 $oldMin = 0; 220 $oldMax = 1; 221 222 $newMin = 127; 223 $newMax = 0; 224 225 return ceil(((($input- $oldMin) * ($newMax - $newMin)) / ($oldMax - $oldMin)) + $newMin); 226 } 227} 228