[ Index ] |
|
Code source de Horde 3.1.3 |
1 <?php 2 3 require_once 'Horde/Util.php'; 4 5 /** 6 * This class defines the Horde_Image:: API, and also provides some 7 * utility functions, such as generating highlights of a color. 8 * 9 * $Horde: framework/Image/Image.php,v 1.39.10.13 2006/01/01 21:28:22 jan Exp $ 10 * 11 * Copyright 2002-2006 Chuck Hagenbuch <chuck@horde.org> 12 * 13 * See the enclosed file COPYING for license information (LGPL). If you 14 * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html. 15 * 16 * @author Chuck Hagenbuch <chuck@horde.org> 17 * @since Horde 3.0 18 * @package Horde_Image 19 */ 20 class Horde_Image { 21 22 /** 23 * Current color. 24 * 25 * @var string 26 */ 27 var $_rgb = 'ff0000'; 28 29 /** 30 * Background color. 31 * 32 * @var string 33 */ 34 var $_background = 'white'; 35 36 /** 37 * Observers. 38 * 39 * @var array 40 */ 41 var $_observers = array(); 42 43 /** 44 * Capabilites of this driver. 45 * 46 * @var array 47 */ 48 var $_capabilities = array(); 49 50 /** 51 * The current image data. 52 * 53 * @var string 54 */ 55 var $_data = ''; 56 57 /** 58 * The current image id. 59 * 60 * @var string 61 */ 62 var $_id = ''; 63 64 /** 65 * The current width of the image data. 66 * 67 * @var integer 68 */ 69 var $_width = 0; 70 71 /** 72 * The current height of the image data. 73 * 74 * @var integer 75 */ 76 var $_height = 0; 77 78 /** 79 * A directory for temporary files. 80 * 81 * @var string 82 */ 83 var $_tmpdir; 84 85 /** 86 * Constructor. 87 * 88 * @param string $rgb The base color for generated pixels/images. 89 */ 90 function Horde_Image($params) 91 { 92 $this->_tmpdir = $params['temp']; 93 if (isset($params['width'])) { 94 $this->_width = $params['width']; 95 } 96 if (isset($params['height'])) { 97 $this->_height = $params['height']; 98 } 99 if (!empty($params['rgb'])) { 100 $this->_rgb = $params['rgb']; 101 } 102 $this->_background = isset($params['background']) ? $params['background'] : 'white'; 103 } 104 105 function getCapabilities() 106 { 107 return $this->_capabilities; 108 } 109 110 function hasCapability($capability) 111 { 112 return in_array($capability, $this->_capabilities); 113 } 114 115 function getLink($url, $title = '') 116 { 117 return Horde::img($url, $title, '', ''); 118 } 119 120 /** 121 * Generate image headers. 122 */ 123 function headers() 124 { 125 header('Content-type: ' . $this->getContentType()); 126 } 127 128 /** 129 * Calculate a lighter (or darker) version of a color. 130 * 131 * @static 132 * 133 * @param string $color An HTML color, e.g.: #ffffcc. 134 * @param string $factor TODO 135 * 136 * @return string A modified HTML color. 137 */ 138 function modifyColor($color, $factor = 0x11) 139 { 140 $r = hexdec(substr($color, 1, 2)) + $factor; 141 $g = hexdec(substr($color, 3, 2)) + $factor; 142 $b = hexdec(substr($color, 5, 2)) + $factor; 143 144 $r = min(max($r, 0), 255); 145 $g = min(max($g, 0), 255); 146 $b = min(max($b, 0), 255); 147 148 return '#' . str_pad(dechex($r), 2, '0', STR_PAD_LEFT) . str_pad(dechex($g), 2, '0', STR_PAD_LEFT) . str_pad(dechex($b), 2, '0', STR_PAD_LEFT); 149 } 150 151 /** 152 * Calculate a more intense version of a color. 153 * 154 * @static 155 * 156 * @param string $color An HTML color, e.g.: #ffffcc. 157 * @param string $factor TODO 158 * 159 * @return string A more intense HTML color. 160 */ 161 function moreIntenseColor($color, $factor = 0x11) 162 { 163 $r = hexdec(substr($color, 1, 2)); 164 $g = hexdec(substr($color, 3, 2)); 165 $b = hexdec(substr($color, 5, 2)); 166 167 if ($r >= $g && $r >= $b) { 168 $g = $g / $r; 169 $b = $b / $r; 170 171 $r += $factor; 172 $g = floor($g * $r); 173 $b = floor($b * $r); 174 } elseif ($g >= $r && $g >= $b) { 175 $r = $r / $g; 176 $b = $b / $g; 177 178 $g += $factor; 179 $r = floor($r * $g); 180 $b = floor($b * $g); 181 } else { 182 $r = $r / $b; 183 $g = $g / $b; 184 185 $b += $factor; 186 $r = floor($r * $b); 187 $g = floor($g * $b); 188 } 189 190 $r = min(max($r, 0), 255); 191 $g = min(max($g, 0), 255); 192 $b = min(max($b, 0), 255); 193 194 return '#' . str_pad(dechex($r), 2, '0', STR_PAD_LEFT) . str_pad(dechex($g), 2, '0', STR_PAD_LEFT) . str_pad(dechex($b), 2, '0', STR_PAD_LEFT); 195 } 196 197 /** 198 * Returns the brightness of a color. 199 * 200 * @static 201 * 202 * @param string $color An HTML color, e.g.: #ffffcc. 203 * 204 * @return integer The brightness on a scale of 0 to 255. 205 */ 206 function brightness($color) 207 { 208 $r = hexdec(substr($color, 1, 2)); 209 $g = hexdec(substr($color, 3, 2)); 210 $b = hexdec(substr($color, 5, 2)); 211 212 return round((($r * 299) + ($g * 587) + ($b * 114)) / 1000); 213 } 214 215 function getRGB($colorname) 216 { 217 require_once dirname(__FILE__) . '/Image/rgb.php'; 218 return isset($GLOBALS['horde_image_rgb_colors'][$colorname]) ? 219 $GLOBALS['horde_image_rgb_colors'][$colorname] : 220 array(0, 0, 0); 221 } 222 223 function getHexColor($colorname) 224 { 225 require_once dirname(__FILE__) . '/Image/rgb.php'; 226 if (isset($GLOBALS['horde_image_rgb_colors'][$colorname])) { 227 list($r, $g, $b) = $GLOBALS['horde_image_rgb_colors'][$colorname]; 228 return '#' . str_pad(dechex(min($r, 255)), 2, '0', STR_PAD_LEFT) . str_pad(dechex(min($g, 255)), 2, '0', STR_PAD_LEFT) . str_pad(dechex(min($b, 255)), 2, '0', STR_PAD_LEFT); 229 } else { 230 return 'black'; 231 } 232 } 233 234 /** 235 * Draw a shaped point at the specified (x,y) point. Useful for 236 * scatter diagrams, debug points, etc. Draws squares, circles, 237 * diamonds, and triangles. 238 * 239 * @param integer $x The x coordinate of the point to brush. 240 * @param integer $y The y coordinate of the point to brush. 241 * @param string $color The color to brush the point with. 242 * @param string $shape What brush to use? Defaults to a square. 243 */ 244 function brush($x, $y, $color = 'black', $shape = 'square') 245 { 246 switch ($shape) { 247 case 'triangle': 248 $verts[0] = array('x' => $x + 3, 'y' => $y + 3); 249 $verts[1] = array('x' => $x, 'y' => $y - 3); 250 $verts[2] = array('x' => $x - 3, 'y' => $y + 3); 251 $this->polygon($verts, $color, $color); 252 break; 253 254 case 'circle': 255 $this->circle($x, $y, 3, $color, $color); 256 break; 257 258 case 'diamond': 259 $verts[0] = array('x' => $x - 3, 'y' => $y); 260 $verts[1] = array('x' => $x, 'y' => $y + 3); 261 $verts[2] = array('x' => $x + 3, 'y' => $y); 262 $verts[3] = array('x' => $x, 'y' => $y - 3); 263 $this->polygon($verts, $color, $color); 264 break; 265 266 case 'square': 267 default: 268 $this->rectangle($x - 2, $y - 2, 4, 4, $color, $color); 269 break; 270 } 271 } 272 273 /** 274 * Add an observer to this image. The observer will be notified 275 * when the image's changes. 276 */ 277 function addObserver($method, &$object) 278 { 279 $this->_observers[] = array($method, &$object); 280 } 281 282 /** 283 * Let observers know that something happened worth acting on. 284 */ 285 function notifyObservers() 286 { 287 for ($i = 0; $i < count($this->_observers); ++$i) { 288 $obj = &$this->_observers[$i][1]; 289 $method = $this->_observers[$i][0]; 290 $obj->$method($this); 291 } 292 } 293 294 /** 295 * Reset the image data. 296 */ 297 function reset() 298 { 299 $this->_data = ''; 300 $this->_id = ''; 301 $this->_width = null; 302 $this->_height = null; 303 $this->_background = 'white'; 304 } 305 306 /** 307 * Get the height and width of the current image data. 308 * 309 * @return array An hash with 'width' containing the width, 310 * 'height' containing the height of the image. 311 */ 312 function getDimensions() 313 { 314 $tmp = $this->toFile(); 315 $details = @getimagesize($tmp); 316 unlink($tmp); 317 318 return array('width' => $details[0], 319 'height' => $details[1]); 320 } 321 322 /** 323 * Load the image data from a string. 324 * 325 * @param string $id An arbitrary id for the image. 326 * @param string $image_data The data to use for the image. 327 */ 328 function loadString($id, $image_data) 329 { 330 if ($id != $this->_id) { 331 $this->reset(); 332 $this->_data = $image_data; 333 $this->_id = $id; 334 } 335 } 336 337 /** 338 * Load the image data from a file. 339 * 340 * @param string $filename The full path and filename to the file to load 341 * the image data from. The filename will also be 342 * used for the image id. 343 * 344 * @return mixed PEAR Error if file does not exist or could not be loaded 345 * otherwise NULL if successful or already loaded. 346 */ 347 function loadFile($filename) 348 { 349 if ($filename != $this->_id) { 350 $this->reset(); 351 if (!file_exists($filename)) { 352 return PEAR::raiseError('The image file ' . $image . ' does not exist.'); 353 } 354 if ($this->_data = file_get_contents($filename)) { 355 $this->_id = $filename; 356 } else { 357 return PEAR::raiseError('Could not load the image file ' . $image); 358 } 359 } 360 } 361 362 function toFile($data = false) 363 { 364 $tmp = Util::getTempFile('img', false, $this->_tmpdir); 365 $fp = @fopen($tmp, 'wb'); 366 fwrite($fp, $data ? $data : $this->raw()); 367 fclose($fp); 368 return $tmp; 369 } 370 371 /** 372 * Display the current image. 373 */ 374 function display() 375 { 376 $this->headers(); 377 echo $this->raw(); 378 } 379 380 /** 381 * Returns the raw data for this image. 382 * 383 * @param boolean $convert If true, the image data will be returned in the 384 * target format, independently from any image 385 * operations. 386 * 387 * @return string The raw image data. 388 */ 389 function raw($convert = false) 390 { 391 return $this->_data; 392 } 393 394 /** 395 * Get an x,y pair on circle, assuming center is 0,0. 396 * 397 * @access private 398 * 399 * @param double $degrees The degrees of arc to get the point for. 400 * @param integer $diameter The diameter of the circle. 401 * 402 * @return array (x coordinate, y coordinate) of the point. 403 */ 404 function _circlePoint($degrees, $diameter) 405 { 406 // Avoid problems with doubles. 407 $degrees += 0.0001; 408 409 return array(cos(deg2rad($degrees)) * ($diameter / 2), 410 sin(deg2rad($degrees)) * ($diameter / 2)); 411 } 412 413 /** 414 * Get point coordinates at the limits of an arc. Only valid for 415 * angles ($end - $start) <= 45 degrees. 416 * 417 * @access private 418 * 419 * @param integer $r The radius of the arc. 420 * @param integer $start The starting angle. 421 * @param integer $end The ending angle. 422 * 423 * @return array The start point, end point, and anchor point. 424 */ 425 function _arcPoints($r, $start, $end) 426 { 427 // Start point. 428 $pts['x1'] = $r * cos(deg2rad($start)); 429 $pts['y1'] = $r * sin(deg2rad($start)); 430 431 // End point. 432 $pts['x2'] = $r * cos(deg2rad($end)); 433 $pts['y2'] = $r * sin(deg2rad($end)); 434 435 // Anchor point. 436 $a3 = ($start + $end) / 2; 437 $r3 = $r / cos(deg2rad(($end - $start) / 2)); 438 $pts['x3'] = $r3 * cos(deg2rad($a3)); 439 $pts['y3'] = $r3 * sin(deg2rad($a3)); 440 441 return $pts; 442 } 443 444 /** 445 * Attempts to return a concrete Horde_Image instance based on $driver. 446 * 447 * @param mixed $driver The type of concrete Horde_Image subclass to 448 * return. This is based on the storage driver 449 * ($driver). The code is dynamically included. If 450 * $driver is an array, then we will look in 451 * $driver[0]/lib/Image/ for the subclass 452 * implementation named $driver[1].php. 453 * @param array $params A hash containing any additional configuration or 454 * connection parameters a subclass might need. 455 * 456 * @return Horde_Image|boolean The newly created concrete Horde_Image 457 * instance, or false on an error. 458 */ 459 function &factory($driver, $params = array()) 460 { 461 if (is_array($driver)) { 462 list($app, $driver) = $driver; 463 } 464 465 if (!empty($app)) { 466 require_once $GLOBALS['registry']->get('fileroot', $app) . '/lib/Image/' . $driver . '.php'; 467 } elseif (@file_exists(dirname(__FILE__) . '/Image/' . $driver . '.php')) { 468 require_once dirname(__FILE__) . '/Image/' . $driver . '.php'; 469 } else { 470 @include_once 'Horde/Image/' . $driver . '.php'; 471 } 472 $class = 'Horde_Image_' . $driver; 473 if (class_exists($class)) { 474 $image = &new $class($params); 475 } else { 476 $image = PEAR::raiseError('Class definition of ' . $class . ' not found.'); 477 } 478 479 return $image; 480 } 481 482 /** 483 * Attempts to return a reference to a concrete Horde_Image instance based 484 * on $driver. It will only create a new instance if no Horde_Image 485 * instance with the same parameters currently exists. 486 * 487 * This should be used if multiple types of image renderers (and, thus, 488 * multiple Horde_Image instances) are required. 489 * 490 * This method must be invoked as: $var = &Horde_Image::singleton() 491 * 492 * @param mixed $driver The type of concrete Horde_Image subclass to 493 * return. This is based on the storage driver 494 * ($driver). The code is dynamically included. If 495 * $driver is an array, then we will look in 496 * $driver[0]/lib/Image/ for the subclass 497 * implementation named $driver[1].php. 498 * @param array $params A hash containing any additional configuration or 499 * connection parameters a subclass might need. 500 * 501 * @return Horde_Image|boolean The concrete Horde_Image reference, or 502 * false on an error. 503 */ 504 function &singleton($driver, $params = array()) 505 { 506 static $instances; 507 if (!isset($instances)) { 508 $instances = array(); 509 } 510 511 $signature = serialize(array($driver, $params)); 512 if (!isset($instances[$signature])) { 513 $instances[$signature] = &Horde_Image::factory($driver, $params); 514 } 515 516 return $instances[$signature]; 517 } 518 519 }
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Sun Feb 25 18:01:28 2007 | par Balluche grâce à PHPXref 0.7 |