[ Index ]
 

Code source de Horde 3.1.3

Accédez au Source d'autres logiciels libresSoutenez Angelica Josefina !

title

Body

[fermer]

/lib/Horde/Image/ -> gd.php (source)

   1  <?php
   2  
   3  require_once dirname(__FILE__) . '/../Image.php';
   4  
   5  /**
   6   * This class implements the Horde_Image:: API for the PHP GD
   7   * extension. It mainly provides some utility functions, such as the
   8   * ability to make pixels, for now.
   9   *
  10   * $Horde: framework/Image/Image/gd.php,v 1.48.10.14 2006/01/01 21:28:22 jan Exp $
  11   *
  12   * Copyright 2002-2006 Chuck Hagenbuch <chuck@horde.org>
  13   *
  14   * See the enclosed file COPYING for license information (LGPL). If you
  15   * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
  16   *
  17   * @author  Chuck Hagenbuch <chuck@horde.org>
  18   * @since   Horde 3.0
  19   * @package Horde_Image
  20   */
  21  class Horde_Image_gd extends Horde_Image {
  22  
  23      /**
  24       * Capabilites of this driver.
  25       *
  26       * @var array
  27       */
  28      var $_capabilities = array('resize',
  29                                 'crop',
  30                                 'rotate',
  31                                 'flip',
  32                                 'mirror',
  33                                 'grayscale',
  34                                 'sepia',
  35                                 'yellowize',
  36                                 'watermark',
  37                                 'canvas',
  38                           );
  39  
  40      /**
  41       * What kind of images should GD generate? Defaults to 'png'.
  42       *
  43       * @var string
  44       */
  45      var $_type = 'png';
  46  
  47      /**
  48       * GD Image resource for the current image data.
  49       *
  50       * @var resource
  51       */
  52      var $_im;
  53  
  54      /**
  55       * String identifier of the current image. New image data will not be
  56       * loaded if the same id is already loaded.
  57       *
  58       * @var string
  59       */
  60      var $_id = '';
  61  
  62      function Horde_Image_gd($params)
  63      {
  64          parent::Horde_Image($params);
  65          if (!empty($params['type'])) {
  66              $this->_type = $params['type'];
  67          }
  68  
  69          if (!empty($params['width'])) {
  70              $this->_im = &$this->_create($this->_width, $this->_height);
  71              $this->_call('imageFill', array($this->_im, 0, 0, $this->allocateColor($this->_background)));
  72          }
  73      }
  74  
  75      function getContentType()
  76      {
  77          return 'image/' . $this->_type;
  78      }
  79  
  80      /**
  81       * Display the current image.
  82       */
  83      function display()
  84      {
  85          $this->headers();
  86          return $this->_call('image' . $this->_type, array($this->_im));
  87      }
  88  
  89      /**
  90       * Returns the raw data for this image.
  91       *
  92       * @param boolean $convert  If true, the image data will be returned in the
  93       *                          target format, independently from any image
  94       *                          operations.
  95       *
  96       * @return string  The raw image data.
  97       */
  98      function raw($convert = false)
  99      {
 100          return Util::bufferOutput('image' . $this->_type, $this->_im);
 101      }
 102  
 103      /**
 104       * Reset the image data.
 105       */
 106      function reset()
 107      {
 108          parent::reset();
 109          if (is_resource($this->_im)) {
 110              return $this->_call('imageDestroy', array($this->_im));
 111          }
 112          return true;
 113      }
 114  
 115      /**
 116       * Get the height and width of the current image.
 117       *
 118       * @return array  An hash with 'width' containing the width,
 119       *                'height' containing the height of the image.
 120       */
 121      function getDimensions()
 122      {
 123          if (is_a($this->_im, 'PEAR_Error')) {
 124              return $this->_im;
 125          } elseif (is_resource($this->_im)) {
 126              return array('width' => $this->_call('imageSX', array($this->_im)),
 127                           'height' => $this->_call('imageSY', array($this->_im)));
 128          } else {
 129              return array('width' => 0, 'height' => 0);
 130          }
 131      }
 132  
 133      /**
 134       * Creates a color that can be accessed in this object. When a
 135       * color is set, the integer resource of it is returned.
 136       *
 137       * @param string $name  The name of the color.
 138       *
 139       * @return integer  The resource of the color that can be passed to GD.
 140       */
 141      function allocateColor($name)
 142      {
 143          static $colors = array();
 144  
 145          if (empty($colors[$name])) {
 146              list($r, $g, $b) = $this->getRGB($name);
 147              $colors[$name] = $this->_call('imageColorAllocate', array($this->_im, $r, $g, $b));
 148          }
 149  
 150          return $colors[$name];
 151      }
 152  
 153      function getFont($font)
 154      {
 155          switch ($font) {
 156          case 'tiny':
 157              return 1;
 158  
 159          case 'medium':
 160              return 3;
 161  
 162          case 'large':
 163              return 4;
 164  
 165          case 'giant':
 166              return 5;
 167  
 168          case 'small':
 169          default:
 170              return 2;
 171          }
 172      }
 173  
 174      /**
 175       * Load the image data from a string.
 176       *
 177       * @param string $id          An arbitrary id for the image.
 178       * @param string $image_data  The data to use for the image.
 179       */
 180      function loadString($id, $image_data)
 181      {
 182          if ($id != $this->_id) {
 183              if ($this->_im) {
 184                  if (is_a($result = $this->reset(), 'PEAR_Error')) {
 185                      return $result;
 186                  }
 187              }
 188              $this->_im = &$this->_call('imageCreateFromString', array($image_data));
 189              $this->_id = $id;
 190              if (is_a($this->_im, 'PEAR_Error')) {
 191                  return $this->_im;
 192              }
 193          }
 194      }
 195  
 196      /**
 197       * Load the image data from a file.
 198       *
 199       * @param string $filename  The full path and filename to the file to load
 200       *                          the image data from. The filename will also be
 201       *                          used for the image id.
 202       *
 203       * @return mixed  PEAR Error if file does not exist or could not be loaded
 204       *                otherwise NULL if successful or already loaded.
 205       */
 206      function loadFile($filename)
 207      {
 208          if (is_a($result = $this->reset(), 'PEAR_Error')) {
 209              return $result;
 210          }
 211  
 212          if (is_a($info = $this->_call('getimagesize', array($filename)), 'PEAR_Error')) {
 213              return $info;
 214          }
 215  
 216          if (is_array($info)) {
 217              switch ($info[2]) {
 218              case 1:
 219                  if (function_exists('imagecreatefromgif')) {
 220                      $this->_im = &$this->_call('imagecreatefromgif', array($filename));
 221                  }
 222                  break;
 223              case 2:
 224                  $this->_im = &$this->_call('imagecreatefromjpeg', array($filename));
 225                  break;
 226              case 3:
 227                  $this->_im = &$this->_call('imagecreatefrompng', array($filename));
 228                  break;
 229              case 15:
 230                  if (function_exists('imagecreatefromgwbmp')) {
 231                      $this->_im = &$this->_call('imagecreatefromgwbmp', array($filename));
 232                  }
 233                  break;
 234              case 16:
 235                  $this->_im = &$this->_call('imagecreatefromxbm', array($filename));
 236                  break;
 237              }
 238          }
 239  
 240          if (is_a($this->_im, 'PEAR_Error')) {
 241              return $this->_im;
 242          }
 243  
 244          if (is_resource($this->_im)) {
 245              return;
 246          }
 247  
 248          $result = parent::loadFile($filename);
 249          if (is_a($result, 'PEAR_Error')) {
 250              return $result;
 251          }
 252          return $this->_im = &$this->_call('imageCreateFromString', array($this->_data));
 253      }
 254  
 255      /**
 256       * Resize the current image.
 257       *
 258       * @param integer $width      The new width.
 259       * @param integer $height     The new height.
 260       * @param boolean $ratio      Maintain original aspect ratio.
 261       */
 262      function resize($width, $height, $ratio = true)
 263      {
 264          /* Abort if we're asked to divide by zero, or truncate the
 265           * image completely in either direction. */
 266          if (!$width || !$height) {
 267              return;
 268          }
 269  
 270          if ($ratio) {
 271              if ($width / $height > $this->_call('imageSX', array($this->_im)) / $this->_call('imageSY', array($this->_im))) {
 272                  $width = $height * $this->_call('imageSX', array($this->_im)) / $this->_call('imageSY', array($this->_im));
 273              } else {
 274                  $height = $width * $this->_call('imageSY', array($this->_im)) / $this->_call('imageSX', array($this->_im));
 275              }
 276          }
 277  
 278          $im = $this->_im;
 279          $this->_im = &$this->_create($width, $height);
 280          if (is_a($this->_im, 'PEAR_Error')) {
 281              return $this->_im;
 282          }
 283          if (is_a($result = $this->_call('imageFill', array($this->_im, 0, 0, $this->_call('imageColorAllocate', array($this->_im, 255, 255, 255)))), 'PEAR_Error')) {
 284              return $result;
 285          }
 286          if (is_a($this->_call('imageCopyResampled', array($this->_im, $im, 0, 0, 0, 0, $width, $height, $this->_call('imageSX', array($im)), $this->_call('imageSY', array($im)))), 'PEAR_Error')) {
 287              return $this->_call('imageCopyResized', array($this->_im, $im, 0, 0, 0, 0, $width, $height, $this->_call('imageSX', array($im)), $this->_call('imageSY', array($im))));
 288          }
 289      }
 290  
 291      /**
 292       * Crop the current image.
 293       *
 294       * @param integer $x1  The top left corner of the cropped image.
 295       * @param integer $y1  The top right corner of the cropped image.
 296       * @param integer $x2  The bottom left corner of the cropped image.
 297       * @param integer $y2  The bottom right corner of the cropped image.
 298       */
 299      function crop($x1, $y1, $x2, $y2)
 300      {
 301          $im = $this->_im;
 302          $this->_im = &$this->_create($x2 - $x1, $y2 - $y1);
 303          if (is_a($this->_im, 'PEAR_Error')) {
 304              return $this->_im;
 305          }
 306          return $this->_call('imageCopy', array($this->_im, $im, 0, 0, $x1, $y1, $x2 - $x1, $y2 - $y1));
 307      }
 308  
 309      /**
 310       * Rotate the current image.
 311       *
 312       * @param integer $angle       The angle to rotate the image by,
 313       *                             in the clockwise direction
 314       * @param integer $background  The background color to fill any triangles
 315       */
 316      function rotate($angle, $background = 'white')
 317      {
 318          if (!function_exists('imagerotate')) {
 319              return;
 320          }
 321  
 322          $background = $this->allocateColor($background);
 323          if (is_a($background, 'PEAR_Error')) {
 324              return $background;
 325          }
 326  
 327          switch ($angle) {
 328          case '90':
 329              $x = $this->_call('imageSX', array($this->_im));
 330              $y = $this->_call('imageSY', array($this->_im));
 331              $xymax = max($x, $y);
 332  
 333              $im = &$this->_create($xymax, $xymax);
 334              if (is_a($im, 'PEAR_Error')) {
 335                  return $im;
 336              }
 337              if (is_a($result = $this->_call('imageCopy', array($im, $this->_im, 0, 0, 0, 0, $x, $y)), 'PEAR_Error')) {
 338                  return $result;
 339              }
 340              $im = &$this->_call('imageRotate', array($im, 270, $background));
 341              if (is_a($im, 'PEAR_Error')) {
 342                  return $im;
 343              }
 344              $this->_im = $im;
 345              $im = &$this->_create($y, $x);
 346              if (is_a($im, 'PEAR_Error')) {
 347                  return $im;
 348              }
 349              if ($x < $y) {
 350                  if (is_a($result = $this->_call('imageCopy', array($im, $this->_im, 0, 0, 0, 0, $xymax, $xymax)), 'PEAR_Error')) {
 351                      return $result;
 352                  }
 353              } elseif ($x > $y) {
 354                  if (is_a($result = $this->_call('imageCopy', array($im, $this->_im, 0, 0, $xymax - $y, $xymax - $x, $xymax, $xymax)), 'PEAR_Error')) {
 355                      return $result;
 356                  }
 357              }
 358              $this->_im = $im;
 359              break;
 360  
 361          default:
 362              $this->_im = &$this->_call('imageRotate', array($this->_im, 360 - $angle, $background));
 363              if (is_a($this->_im, 'PEAR_Error')) {
 364                  return $this->_im;
 365              }
 366              break;
 367          }
 368      }
 369  
 370      /**
 371       * Flip the current image.
 372       */
 373      function flip()
 374      {
 375          $x = $this->_call('imageSX', array($this->_im));
 376          $y = $this->_call('imageSY', array($this->_im));
 377  
 378          $im = &$this->_create($x, $y);
 379          if (is_a($im, 'PEAR_Error')) {
 380              return $im;
 381          }
 382          for ($curY = 0; $curY < $y; $curY++) {
 383              if (is_a($result = $this->_call('imageCopy', array($im, $this->_im, 0, $y - ($curY + 1), 0, $curY, $x, 1)), 'PEAR_Error')) {
 384                  return $result;
 385              }
 386          }
 387  
 388          $this->_im = $im;
 389      }
 390  
 391      /**
 392       * Mirror the current image.
 393       */
 394      function mirror()
 395      {
 396          $x = $this->_call('imageSX', array($this->_im));
 397          $y = $this->_call('imageSY', array($this->_im));
 398  
 399          $im = &$this->_create($x, $y);
 400          if (is_a($im, 'PEAR_Error')) {
 401              return $im;
 402          }
 403          for ($curX = 0; $curX < $x; $curX++) {
 404              if (is_a($result = $this->_call('imageCopy', array($im, $this->_im, $x - ($curX + 1), 0, $curX, 0, 1, $y)), 'PEAR_Error')) {
 405                  return $result;
 406              }
 407          }
 408  
 409          $this->_im = $im;
 410      }
 411  
 412      /**
 413       * Convert the current image to grayscale.
 414       */
 415      function grayscale()
 416      {
 417          $rateR = .229;
 418          $rateG = .587;
 419          $rateB = .114;
 420          $whiteness = 3;
 421  
 422          if (function_exists('imageistruecolor') && $this->_call('imageIsTrueColor', array($this->_im)) === true) {
 423              if (is_a($result = $this->_call('imageTrueColorToPalette', array($this->_im, true, 256)), 'PEAR_Error')) {
 424                  return $result;
 425              }
 426          }
 427  
 428          $colors = min(256, $this->_call('imageColorsTotal', array($this->_im)));
 429          for ($x = 0; $x < $colors; $x++) {
 430              $src = $this->_call('imageColorsForIndex', array($this->_im, $x));
 431              if (is_a($src, 'PEAR_Error')) {
 432                  return $src;
 433              }
 434              $new = min(255, abs($src['red'] * $rateR + $src['green'] * $rateG + $src['blue'] * $rateB) + $whiteness);
 435              if (is_a($result = $this->_call('imageColorSet', array($this->_im, $x, $new, $new, $new)), 'PEAR_Error')) {
 436                  return $result;
 437              }
 438          }
 439      }
 440  
 441      /**
 442       * Sepia filter.
 443       *
 444       * Basically turns the image to grayscale and then adds some
 445       * defined tint on it (R += 30, G += 43, B += -23) so it will
 446       * appear to be a very old picture.
 447       */
 448      function sepia()
 449      {
 450          $tintR = 80;
 451          $tintG = 43;
 452          $tintB = -23;
 453          $rateR = .229;
 454          $rateG = .587;
 455          $rateB = .114;
 456          $whiteness = 3;
 457  
 458          if ($this->_call('imageIsTrueColor', array($this->_im)) === true) {
 459              if (is_a($result = $this->_call('imageTrueColorToPalette', array($this->_im, true, 256)), 'PEAR_Error')) {
 460                  return $result;
 461              }
 462          }
 463  
 464          $colors = max(256, $this->_call('imageColorsTotal', array($this->_im)));
 465          for ($x = 0; $x < $colors; $x++) {
 466              $src = $this->_call('imageColorsForIndex', array($this->_im, $x));
 467              if (is_a($src, 'PEAR_Error')) {
 468                  return $src;
 469              }
 470              $new = min(255, abs($src['red'] * $rateR + $src['green'] * $rateG + $src['blue'] * $rateB) + $whiteness);
 471              $r = min(255, $new + $tintR);
 472              $g = min(255, $new + $tintG);
 473              $b = min(255, $new + $tintB);
 474              if (is_a($result = $this->_call('imageColorSet', array($this->_im, $x, $r, $g, $b)), 'PEAR_Error')) {
 475                  return $result;
 476              }
 477          }
 478      }
 479  
 480      /**
 481       * Yellowize filter.
 482       *
 483       * Adds a layer of yellow that can be transparent or solid. If
 484       * $intensityA is 255 the image will be 0% transparent (solid).
 485       *
 486       * @param integer $intensityY  How strong should the yellow (red and green) be? (0-255)
 487       * @param integer $intensityB  How weak should the blue be? (>= 2, in the positive limit it will be make BLUE 0)
 488       */
 489      function yellowize($intensityY = 50, $intensityB = 3)
 490      {
 491          if ($this->_call('imageIsTrueColor', array($this->_im)) === true) {
 492              if (is_a($result = $this->_call('imageTrueColorToPalette', array($this->_im, true, 256)), 'PEAR_Error')) {
 493                  return $result;
 494              }
 495          }
 496  
 497          $colors = max(256, $this->_call('imageColorsTotal', array($this->_im)));
 498          for ($x = 0; $x < $colors; $x++) {
 499              $src = $this->_call('imageColorsForIndex', array($this->_im, $x));
 500              if (is_a($src, 'PEAR_Error')) {
 501                  return $src;
 502              }
 503              $r = min($src['red'] + $intensityY, 255);
 504              $g = min($src['green'] + $intensityY, 255);
 505              $b = max(($r + $g) / max($intensityB, 2), 0);
 506              if (is_a($result = $this->_call('imageColorSet', array($this->_im, $x, $r, $g, $b)), 'PEAR_Error')) {
 507                  return $result;
 508              }
 509          }
 510      }
 511  
 512      function watermark($text, $halign = 'right', $valign = 'bottom', $font = 'small')
 513      {
 514          $color = $this->_call('imageColorClosest', array($this->_im, 255, 255, 255));
 515          if (is_a($color, 'PEAR_Error')) {
 516              return $color;
 517          }
 518          $shadow = $this->_call('imageColorClosest', array($this->_im, 0, 0, 0));
 519          if (is_a($shadow, 'PEAR_Error')) {
 520              return $shadow;
 521          }
 522  
 523          // Shadow offset in pixels.
 524          $drop = 1;
 525  
 526          // Maximum text width.
 527          $maxwidth = 200;
 528  
 529          // Amount of space to leave between the text and the image
 530          // border.
 531          $padding = 10;
 532  
 533          $f = $this->getFont($font);
 534          $fontwidth = $this->_call('imageFontWidth', array($f));
 535          if (is_a($fontwidth, 'PEAR_Error')) {
 536              return $fontwidth;
 537          }
 538          $fontheight = $this->_call('imageFontHeight', array($f));
 539          if (is_a($fontheight, 'PEAR_Error')) {
 540              return $fontheight;
 541          }
 542  
 543          // So that shadow is not off the image with right align and
 544          // bottom valign.
 545          $margin = floor($padding + $drop) / 2;
 546  
 547          if ($maxwidth) {
 548              $maxcharsperline = floor(($maxwidth - ($margin * 2)) / $fontwidth);
 549              $text = wordwrap($text, $maxcharsperline, "\n", 1);
 550          }
 551  
 552          // Split $text into individual lines.
 553          $lines = explode("\n", $text);
 554  
 555          switch ($valign) {
 556          case 'center':
 557              $y = ($this->_call('imageSY', array($this->_im)) - ($fontheight * count($lines))) / 2;
 558              break;
 559  
 560          case 'bottom':
 561              $y = $this->_call('imageSY', array($this->_im)) - (($fontheight * count($lines)) + $margin);
 562              break;
 563  
 564          default:
 565              $y = $margin;
 566              break;
 567          }
 568  
 569          switch ($halign) {
 570          case 'right':
 571              foreach ($lines as $line) {
 572                  if (is_a($result = $this->_call('imageString', array($this->_im, $f, ($this->_call('imageSX', array($this->_im)) - $fontwidth * strlen($line)) - $margin + $drop, ($y + $drop), $line, $shadow)), 'PEAR_Error')) {
 573                      return $result;
 574                  }
 575                  $result = $this->_call('imageString', array($this->_im, $f, ($this->_call('imageSX', array($this->_im)) - $fontwidth * strlen($line)) - $margin, $y, $line, $color));
 576                  $y += $fontheight;
 577              }
 578              break;
 579  
 580          case 'center':
 581              foreach ($lines as $line) {
 582                  if (is_a($result = $this->_call('imageString', array($this->_im, $f, floor(($this->_call('imageSX', array($this->_im)) - $fontwidth * strlen($line)) / 2) + $drop, ($y + $drop), $line, $shadow)), 'PEAR_Error')) {
 583                      return $result;
 584                  }
 585                  $result = $this->_call('imageString', array($this->_im, $f, floor(($this->_call('imageSX', array($this->_im)) - $fontwidth * strlen($line)) / 2), $y, $line, $color));
 586                  $y += $fontheight;
 587              }
 588              break;
 589  
 590          default:
 591              foreach ($lines as $line) {
 592                  if (is_a($result = $this->_call('imageString', array($this->_im, $f, $margin + $drop, ($y + $drop), $line, $shadow)), 'PEAR_Error')) {
 593                      return $result;
 594                  }
 595                  $result = $this->_call('imageString', array($this->_im, $f, $margin, $y, $line, $color));
 596                  $y += $fontheight;
 597              }
 598              break;
 599          }
 600  
 601          if (is_a($result, 'PEAR_Error')) {
 602              return $result;
 603          }
 604      }
 605  
 606      /**
 607       * Draws a text string on the image in a specified location, with
 608       * the specified style information.
 609       *
 610       * @param string  $text       The text to draw.
 611       * @param integer $x          The left x coordinate of the start of the
 612       *                            text string.
 613       * @param integer $y          The top y coordinate of the start of the text
 614       *                            string.
 615       * @param string  $font       The font identifier you want to use for the
 616       *                            text.
 617       * @param string  $color      The color that you want the text displayed in.
 618       * @param integer $direction  An integer that specifies the orientation of
 619       *                            the text.
 620       */
 621      function text($string, $x, $y, $font = 'monospace', $color = 'black', $direction = 0)
 622      {
 623          $c = $this->allocateColor($color);
 624          if (is_a($c, 'PEAR_Error')) {
 625              return $c;
 626          }
 627          $f = $this->getFont($font);
 628          switch ($direction) {
 629          case -90:
 630          case 270:
 631              $result = $this->_call('imageStringUp', array($this->_im, $f, $x, $y, $string, $c));
 632              break;
 633  
 634          case 0:
 635          default:
 636              $result = $this->_call('imageString', array($this->_im, $f, $x, $y, $string, $c));
 637          }
 638  
 639          return $result;
 640      }
 641  
 642      /**
 643       * Draw a circle.
 644       *
 645       * @param integer $x     The x co-ordinate of the centre.
 646       * @param integer $y     The y co-ordinate of the centre.
 647       * @param integer $r     The radius of the circle.
 648       * @param string $color  The line color of the circle.
 649       * @param string $fill   The color to fill the circle.
 650       */
 651      function circle($x, $y, $r, $color, $fill = null)
 652      {
 653          $c = $this->allocateColor($color);
 654          if (is_a($c, 'PEAR_Error')) {
 655              return $c;
 656          }
 657          if (is_null($fill)) {
 658              $result = $this->_call('imageEllipse', array($this->_im, $x, $y, $r * 2, $r * 2, $c));
 659          } else {
 660              if ($fill !== $color) {
 661                  $fillColor = $this->allocateColor($fill);
 662                  if (is_a($fillColor, 'PEAR_Error')) {
 663                      return $fillColor;
 664                  }
 665                  if (is_a($result = $this->_call('imageFilledEllipse', array($this->_im, $x, $y, $r * 2, $r * 2, $fillColor)), 'PEAR_Error')) {
 666                      return $result;
 667                  }
 668                  $result = $this->_call('imageEllipse', array($this->_im, $x, $y, $r * 2, $r * 2, $c));
 669              } else {
 670                  $result = $this->_call('imageFilledEllipse', array($this->_im, $x, $y, $r * 2, $r * 2, $c));
 671              }
 672          }
 673          if (is_a($result, 'PEAR_Error')) {
 674              return $result;
 675          }
 676      }
 677  
 678      /**
 679       * Draw a polygon based on a set of vertices.
 680       *
 681       * @param array $vertices  An array of x and y labeled arrays
 682       *                         (eg. $vertices[0]['x'], $vertices[0]['y'], ...).
 683       * @param string $color    The color you want to draw the polygon with.
 684       * @param string $fill     The color to fill the polygon.
 685       */
 686      function polygon($verts, $color, $fill = 'none')
 687      {
 688          $vertices = array();
 689          foreach ($verts as $vert) {
 690              $vertices[] = $vert['x'];
 691              $vertices[] = $vert['y'];
 692          }
 693  
 694          if ($fill != 'none') {
 695              $f = $this->allocateColor($fill);
 696              if (is_a($f, 'PEAR_Error')) {
 697                  return $f;
 698              }
 699              if (is_a($result = $this->_call('imageFilledPolygon', array($this->_im, $vertices, count($verts), $f)), 'PEAR_Error')) {
 700                  return $result;
 701              }
 702          }
 703  
 704          if ($fill == 'none' || $fill != $color) {
 705              $c = $this->allocateColor($color);
 706              if (is_a($c, 'PEAR_Error')) {
 707                  return $c;
 708              }
 709              if (is_a($result = $this->_call('imagePolygon', array($this->_im, $vertices, count($verts), $c)), 'PEAR_Error')) {
 710                  return $result;
 711              }
 712          }
 713      }
 714  
 715      /**
 716       * Draw a rectangle.
 717       *
 718       * @param integer $x       The left x-coordinate of the rectangle.
 719       * @param integer $y       The top y-coordinate of the rectangle.
 720       * @param integer $width   The width of the rectangle.
 721       * @param integer $height  The height of the rectangle.
 722       * @param string $color    The line color of the rectangle.
 723       * @param string $fill     The color to fill the rectangle with.
 724       */
 725      function rectangle($x, $y, $width, $height, $color = 'black', $fill = 'none')
 726      {
 727          if ($fill != 'none') {
 728              $f = $this->allocateColor($fill);
 729              if (is_a($f, 'PEAR_Error')) {
 730                  return $f;
 731              }
 732              if (is_a($result = $this->_call('imageFilledRectangle', array($this->_im, $x, $y, $x + $width, $y + $height, $f)), 'PEAR_Error')) {
 733                  return $result;
 734              }
 735          }
 736  
 737          if ($fill == 'none' || $fill != $color) {
 738              $c = $this->allocateColor($color);
 739              if (is_a($c, 'PEAR_Error')) {
 740                  return $c;
 741              }
 742              if (is_a($result = $this->_call('imageRectangle', array($this->_im, $x, $y, $x + $width, $y + $height, $c)), 'PEAR_Error')) {
 743                  return $result;
 744              }
 745          }
 746      }
 747  
 748      /**
 749       * Draw a rounded rectangle.
 750       *
 751       * @param integer $x       The left x-coordinate of the rectangle.
 752       * @param integer $y       The top y-coordinate of the rectangle.
 753       * @param integer $width   The width of the rectangle.
 754       * @param integer $height  The height of the rectangle.
 755       * @param integer $round   The width of the corner rounding.
 756       * @param string $color    The line color of the rectangle.
 757       * @param string $fill     The color to fill the rounded rectangle with.
 758       */
 759      function roundedRectangle($x, $y, $width, $height, $round, $color = 'black', $fill = 'none')
 760      {
 761          if ($round <= 0) {
 762              // Optimize out any calls with no corner rounding.
 763              return $this->rectangle($x, $y, $width, $height, $color, $fill);
 764          }
 765  
 766          $c = $this->allocateColor($color);
 767          if (is_a($c, 'PEAR_Error')) {
 768              return $c;
 769          }
 770  
 771          // Set corner points to avoid lots of redundant math.
 772          $x1 = $x + $round;
 773          $y1 = $y + $round;
 774  
 775          $x2 = $x + $width - $round;
 776          $y2 = $y + $round;
 777  
 778          $x3 = $x + $width - $round;
 779          $y3 = $y + $height - $round;
 780  
 781          $x4 = $x + $round;
 782          $y4 = $y + $height - $round;
 783  
 784          $r = $round * 2;
 785  
 786          // Calculate the upper left arc.
 787          $p1 = $this->_arcPoints($round, 180, 225);
 788          $p2 = $this->_arcPoints($round, 225, 270);
 789  
 790          // Calculate the upper right arc.
 791          $p3 = $this->_arcPoints($round, 270, 315);
 792          $p4 = $this->_arcPoints($round, 315, 360);
 793  
 794          // Calculate the lower right arc.
 795          $p5 = $this->_arcPoints($round, 0, 45);
 796          $p6 = $this->_arcPoints($round, 45, 90);
 797  
 798          // Calculate the lower left arc.
 799          $p7 = $this->_arcPoints($round, 90, 135);
 800          $p8 = $this->_arcPoints($round, 135, 180);
 801  
 802          // Draw the corners - upper left, upper right, lower right,
 803          // lower left.
 804          if (is_a($result = $this->_call('imageArc', array($this->_im, $x1, $y1, $r, $r, 180, 270, $c)), 'PEAR_Error')) {
 805              return $result;
 806          }
 807          if (is_a($result = $this->_call('imageArc', array($this->_im, $x2, $y2, $r, $r, 270, 360, $c)), 'PEAR_Error')) {
 808              return $result;
 809          }
 810          if (is_a($result = $this->_call('imageArc', array($this->_im, $x3, $y3, $r, $r, 0, 90, $c)), 'PEAR_Error')) {
 811              return $result;
 812          }
 813          if (is_a($result = $this->_call('imageArc', array($this->_im, $x4, $y4, $r, $r, 90, 180, $c)), 'PEAR_Error')) {
 814              return $result;
 815          }
 816  
 817          // Draw the connecting sides - top, right, bottom, left.
 818          if (is_a($result = $this->_call('imageLine', array($this->_im, $x1 + $p2['x2'], $y1 + $p2['y2'], $x2 + $p3['x1'], $y2 + $p3['y1'], $c)), 'PEAR_Error')) {
 819              return $result;
 820          }
 821          if (is_a($result = $this->_call('imageLine', array($this->_im, $x2 + $p4['x2'], $y2 + $p4['y2'], $x3 + $p5['x1'], $y3 + $p5['y1'], $c)), 'PEAR_Error')) {
 822              return $result;
 823          }
 824          if (is_a($result = $this->_call('imageLine', array($this->_im, $x3 + $p6['x2'], $y3 + $p6['y2'], $x4 + $p7['x1'], $y4 + $p7['y1'], $c)), 'PEAR_Error')) {
 825              return $result;
 826          }
 827          if (is_a($result = $this->_call('imageLine', array($this->_im, $x4 + $p8['x2'], $y4 + $p8['y2'], $x1 + $p1['x1'], $y1 + $p1['y1'], $c)), 'PEAR_Error')) {
 828              return $result;
 829          }
 830  
 831          if ($fill != 'none') {
 832              $f = $this->allocateColor($fill);
 833              if (is_a($f, 'PEAR_Error')) {
 834                  return $f;
 835              }
 836              if (is_a($result = $this->_call('imageFillToBorder', array($this->_im, $x + ($width / 2), $y + ($height / 2), $c, $f)), 'PEAR_Error')) {
 837                  return $result;
 838              }
 839          }
 840      }
 841  
 842      /**
 843       * Draw a line.
 844       *
 845       * @param integer $x0    The x co-ordinate of the start.
 846       * @param integer $y0    The y co-ordinate of the start.
 847       * @param integer $x1    The x co-ordinate of the end.
 848       * @param integer $y1    The y co-ordinate of the end.
 849       * @param string $color  The line color.
 850       * @param string $width  The width of the line.
 851       */
 852      function line($x1, $y1, $x2, $y2, $color = 'black', $width = 1)
 853      {
 854          $c = $this->allocateColor($color);
 855          if (is_a($c, 'PEAR_Error')) {
 856              return $c;
 857          }
 858  
 859          // Don't need to do anything special for single-width lines.
 860          if ($width == 1) {
 861              $result = $this->_call('imageLine', array($this->_im, $x1, $y1, $x2, $y2, $c));
 862          } elseif ($x1 == $x2) {
 863              // For vertical lines, we can just draw a vertical
 864              // rectangle.
 865              $left = $x1 - floor(($width - 1) / 2);
 866              $right = $x1 + floor($width / 2);
 867              $result = $this->_call('imageFilledRectangle', array($this->_im, $left, $y1, $right, $y2, $c));
 868          } elseif ($y1 == $y2) {
 869              // For horizontal lines, we can just draw a horizontal
 870              // filled rectangle.
 871              $top = $y1 - floor($width / 2);
 872              $bottom = $y1 + floor(($width - 1) / 2);
 873              $result = $this->_call('imageFilledRectangle', array($this->_im, $x1, $top, $x2, $bottom, $c));
 874          } else {
 875              // Angled lines.
 876  
 877              // Make sure that the end points of the line are
 878              // perpendicular to the line itself.
 879              $a = atan2($y1 - $y2, $x2 - $x1);
 880              $dx = (sin($a) * $width / 2);
 881              $dy = (cos($a) * $width / 2);
 882  
 883              $verts = array($x2 + $dx, $y2 + $dy, $x2 - $dx, $y2 - $dy, $x1 - $dx, $y1 - $dy, $x1 + $dx, $y1 + $dy);
 884              $result = $this->_call('imageFilledPolygon', array($this->_im, $verts, count($verts) / 2, $c));
 885          }
 886  
 887          return $result;
 888      }
 889  
 890      /**
 891       * Draw a dashed line.
 892       *
 893       * @param integer $x0           The x co-ordinate of the start.
 894       * @param integer $y0           The y co-ordinate of the start.
 895       * @param integer $x1           The x co-ordinate of the end.
 896       * @param integer $y1           The y co-ordinate of the end.
 897       * @param string $color         The line color.
 898       * @param string $width         The width of the line.
 899       * @param integer $dash_length  The length of a dash on the dashed line
 900       * @param integer $dash_space   The length of a space in the dashed line
 901       */
 902      function dashedLine($x0, $y0, $x1, $y1, $color = 'black', $width = 1, $dash_length = 2, $dash_space = 2)
 903      {
 904          $c = $this->allocateColor($color);
 905          if (is_a($c, 'PEAR_Error')) {
 906              return $c;
 907          }
 908          $w = $this->allocateColor('white');
 909          if (is_a($w, 'PEAR_Error')) {
 910              return $w;
 911          }
 912  
 913          // Set up the style array according to the $dash_* parameters.
 914          $style = array();
 915          for ($i = 0; $i < $dash_length; $i++) {
 916              $style[] = $c;
 917          }
 918          for ($i = 0; $i < $dash_space; $i++) {
 919              $style[] = $w;
 920          }
 921  
 922          if (is_a($result = $this->_call('imageSetStyle', array($this->_im, $style)), 'PEAR_Error')) {
 923              return $result;
 924          }
 925          if (is_a($result = $this->_call('imageSetThickness', array($this->_im, $width)), 'PEAR_Error')) {
 926              return $result;
 927          }
 928          return $this->_call('imageLine', array($this->_im, $x0, $y0, $x1, $y1, IMG_COLOR_STYLED));
 929      }
 930  
 931      /**
 932       * Draw a polyline (a non-closed, non-filled polygon) based on a
 933       * set of vertices.
 934       *
 935       * @param array $vertices  An array of x and y labeled arrays
 936       *                         (eg. $vertices[0]['x'], $vertices[0]['y'], ...).
 937       * @param string $color    The color you want to draw the line with.
 938       * @param string $width    The width of the line.
 939       */
 940      function polyline($verts, $color, $width = 1)
 941      {
 942          $first = true;
 943          foreach ($verts as $vert) {
 944              if (!$first) {
 945                  if (is_a($result = $this->line($lastX, $lastY, $vert['x'], $vert['y'], $color, $width), 'PEAR_Error')) {
 946                      return $result;
 947                  }
 948              } else {
 949                  $first = false;
 950              }
 951              $lastX = $vert['x'];
 952              $lastY = $vert['y'];
 953          }
 954      }
 955  
 956      /**
 957       * Draw an arc.
 958       *
 959       * @param integer $x      The x co-ordinate of the centre.
 960       * @param integer $y      The y co-ordinate of the centre.
 961       * @param integer $r      The radius of the arc.
 962       * @param integer $start  The start angle of the arc.
 963       * @param integer $end    The end angle of the arc.
 964       * @param string  $color  The line color of the arc.
 965       * @param string  $fill   The fill color of the arc (defaults to none).
 966       */
 967      function arc($x, $y, $r, $start, $end, $color = 'black', $fill = null)
 968      {
 969          $c = $this->allocateColor($color);
 970          if (is_a($c, 'PEAR_Error')) {
 971              return $c;
 972          }
 973          if (is_null($fill)) {
 974              $result = $this->_call('imageArc', array($this->_im, $x, $y, $r * 2, $r * 2, $start, $end, $c));
 975          } else {
 976              if ($fill !== $color) {
 977                  $f = $this->allocateColor($fill);
 978                  if (is_a($f, 'PEAR_Error')) {
 979                      return $f;
 980                  }
 981                  if (is_a($result = $this->_call('imageFilledArc', array($this->_im, $x, $y, $r * 2, $r * 2, $start, $end, $f, IMG_ARC_PIE)), 'PEAR_Error')) {
 982                      return $result;
 983                  }
 984                  $result = $this->_call('imageFilledArc', array($this->_im, $x, $y, $r * 2, $r * 2, $start, $end, $c, IMG_ARC_EDGED | IMG_ARC_NOFILL));
 985              } else {
 986                  $result = $this->_call('imageFilledArc', array($this->_im, $x, $y, $r * 2, $r * 2, $start, $end, $c, IMG_ARC_PIE));
 987              }
 988          }
 989          return $result;
 990      }
 991  
 992      /**
 993       * Creates an image of the given size.
 994       * If possible the function returns a true color image.
 995       *
 996       * @param integer $width   The image width.
 997       * @param integer $height  The image height.
 998       *
 999       * @return resource|object PEAR Error  The image handler or a PEAR_Error on
1000       *                                     error.
1001       */
1002      function &_create($width, $height)
1003      {
1004          $result = &$this->_call('imageCreateTrueColor', array($width, $height));
1005          if (!is_resource($result)) {
1006              $result = &$this->_call('imageCreate', array($width, $height));
1007          }
1008          return $result;
1009      }
1010  
1011      /**
1012       * Wraps a call to a function of the gd extension.
1013       * If the call produces an error, a PEAR_Error is returned, the function
1014       * result otherwise.
1015       *
1016       * @param string $function  The name of the function to wrap.
1017       * @param array $params     An array with all parameters for that function.
1018       *
1019       * @return mixed  Either the function result or a PEAR_Error if an error
1020       *                occured when executing the function.
1021       */
1022      function &_call($function, $params = null)
1023      {
1024          unset($php_errormsg);
1025          $track = ini_set('track_errors', 1);
1026          $result = @call_user_func_array($function, $params);
1027          if ($track !== false) {
1028              ini_set('track_errors', $track);
1029          }
1030          if (!empty($php_errormsg)) {
1031              require_once 'PEAR.php';
1032              $result = PEAR::raiseError($function . ': ' . $php_errormsg);
1033          }
1034          return $result;
1035      }
1036  
1037  }


Généré le : Sun Feb 25 18:01:28 2007 par Balluche grâce à PHPXref 0.7