Syntax Desktop PHP Cross Reference Web Portal Systems

Source: /admin/includes/php/class.ImageToolbox.php - 1420 lines - 51622 bytes - Summary - Text - Print

Description: Image_Toolbox.class.php -- PHP image manipulation class Copyright (C) 2003 Martin Theimer <pappkamerad@decoded.net>

   1  <?php
   2  /**

   3   * Image_Toolbox.class.php -- PHP image manipulation class

   4   *

   5   * Copyright (C) 2003 Martin Theimer <pappkamerad@decoded.net>

   6   * 

   7   * This program is free software; you can redistribute it and/or modify

   8   * it under the terms of the GNU General Public License as published by

   9   * the Free Software Foundation; either version 2 of the License, or

  10   * (at your option) any later version.

  11   * This program is distributed in the hope that it will be useful,

  12   * but WITHOUT ANY WARRANTY; without even the implied warranty of

  13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

  14   * GNU General Public License <http://www.opensource.org/gpl-license.html>

  15   * for more details..

  16   *

  17   * The latest version of Image_Toolbox can be obtained from:

  18   * http://sourceforge.net/projects/image-toolbox

  19   * http://www.phpclasses.org/image_toolbox

  20   *

  21   * @author Martin Theimer <pappkamerad@decoded.net>

  22   * @copyright Copyright (C) 2003 Martin Theimer

  23   * @version 1.1.0

  24   * @package Image_Toolbox

  25   * @link http://sourceforge.net/projects/image-toolbox

  26   */
  27   
  28  // $Id: class.ImageToolbox.php 8 2005-11-16 21:36:31Z dynamick $

  29  
  30  
  31   /* EXAMPLE WITH SYNTAX DESKTOP

  32   

  33      include_once("admin/includes/php/class.ImageToolbox.php");

  34      if ($Immagine!="") $img="mat/lead_id".$lid.".".$Immagine;

  35      else $img="";

  36      $thumbnail=new Image_Toolbox($img);

  37      $thumbnail->setResizeMethod('resample');

  38      $thumbnail->newOutputSize(140,75,1,false,'#FFFFFF');

  39      $thumbnail->addImage('./img/logo.png');

  40      $thumbnail->blend('right','bottom');

  41      $resultimg="mat/thumb/lead_id".$lid.".".$Immagine;

  42      $thumbnail->save($resultimg,'png8');

  43   

  44   

  45   */
  46  
  47  if (!defined('IMAGE_TOOLBOX_DEFAULT_JPEG_QUALITY')) {
  48      define('IMAGE_TOOLBOX_DEFAULT_JPEG_QUALITY', 75);
  49  }
  50  if (!defined('IMAGE_TOOLBOX_DEFAULT_8BIT_COLORS')) {
  51      define('IMAGE_TOOLBOX_DEFAULT_8BIT_COLORS', 256);
  52  }
  53  if (!defined('IMAGE_TOOLBOX_BIAS_HORIZONTAL')) {
  54      define('IMAGE_TOOLBOX_BIAS_HORIZONTAL', 1);
  55  }
  56  if (!defined('IMAGE_TOOLBOX_BIAS_VERTICAL')) {
  57      define('IMAGE_TOOLBOX_BIAS_VERTICAL', 0);
  58  }
  59  if (!defined('IMAGE_TOOLBOX_BLEND_COPY')) {
  60      define('IMAGE_TOOLBOX_BLEND_COPY', 1);
  61  }
  62  if (!defined('IMAGE_TOOLBOX_BLEND_MULTIPLY')) {
  63      define('IMAGE_TOOLBOX_BLEND_MULTIPLY', 2);
  64  }
  65  if (!defined('IMAGE_TOOLBOX_BLEND_SCREEN')) {
  66      define('IMAGE_TOOLBOX_BLEND_SCREEN', 3);
  67  }
  68  if (!defined('IMAGE_TOOLBOX_BLEND_DIFFERENCE')) {
  69      define('IMAGE_TOOLBOX_BLEND_DIFFERENCE', 4);
  70  }
  71  if (!defined('IMAGE_TOOLBOX_BLEND_NEGATION')) {
  72      define('IMAGE_TOOLBOX_BLEND_NEGATION', 5);
  73  }
  74  if (!defined('IMAGE_TOOLBOX_BLEND_EXCLUTION')) {
  75      define('IMAGE_TOOLBOX_BLEND_EXCLUSION', 6);
  76  }
  77  if (!defined('IMAGE_TOOLBOX_BLEND_OVERLAY')) {
  78      define('IMAGE_TOOLBOX_BLEND_OVERLAY', 7);
  79  }
  80  
  81  /**

  82   * PHP image manipulation class

  83   *

  84   * This class provides an easy to use library to the PHP GD-based imagefunctions

  85   *

  86   * @author Martin Theimer <pappkamerad@decoded.net>

  87   * @copyright 2003, Martin Theimer

  88   * @package Image_Toolbox

  89   * @link http://sourceforge.net/projects/image-toolbox

  90   * @version 1.1.0

  91   */
  92  class Image_Toolbox {
  93  
  94      /**

  95       * The prefix for every error message

  96       * 

  97       * @access private

  98       * @var string

  99       */
 100      var $_error_prefix = 'Image: ';
 101      
 102      /**

 103       * Defines imagetypes and how they are supported by the server

 104       * 

 105       * @access private

 106       * @var array

 107       */
 108      var $_types = array (
 109          1 => array (
 110              'ext' => 'gif',
 111              'mime' => 'image/gif',
 112              'supported' => 0
 113          ),
 114          2 => array (
 115              'ext' => 'jpg',
 116              'mime' => 'image/jpeg',
 117              'supported' => 0
 118          ),
 119          3 => array (
 120              'ext' => 'png',
 121              'mime' => 'image/png',
 122              'supported' => 0
 123          )
 124      );
 125      
 126      /**

 127       * Which PHP image resize function to be used

 128       * imagecopyresampled only supported with GD >= 2.0

 129       * 

 130       * @access private

 131       * @var string

 132       */
 133      var $_resize_function = 'imagecopyresampled';
 134  
 135      /**

 136       * Stores all image resource data

 137       * 

 138       * @access private

 139       * @var array

 140       */
 141      var $_img = array (
 142          'main' => array (
 143              'resource' => 0,
 144              'width' => 0,
 145              'height' => 0,
 146              'bias' => 0,
 147              'aspectratio' => 0,
 148              'type' => 0,
 149              'output_type' => 0,
 150              'indexedcolors' => 0,
 151              'color' => -1
 152          )
 153      );
 154      
 155      /**

 156       * Which PHP image create function to be used

 157       * imagecreatetruecolor only supported with GD >= 2.0

 158       * 

 159       * @access private

 160       * @var string

 161       */
 162      var $_imagecreatefunction = '';
 163      
 164      /**

 165       * The class constructor.

 166       *

 167       * Determines the image features of the server and sets the according values.<br>

 168       * Additionally you can specify a image to be created/loaded. like {@link addImage() addImage}.

 169       * 

 170       * If no parameter is given, no image resource will be generated<br>

 171       * Or:<br>

 172       * <i>string</i> <b>$file</b> imagefile to load<br>

 173       * Or:<br>

 174       * <i>integer</i> <b>$width</b> imagewidth of new image to be created<br>

 175       * <i>integer</i> <b>$height</b> imageheight of new image to be created<br>

 176       * <i>string</i> <b>$fillcolor</b> optional fill the new image with this color (hexformat, e.g. '#FF0000')<br>

 177       */
 178  	function Image_Toolbox() {
 179          $args = func_get_args();
 180          $argc = func_num_args();
 181          
 182          //get GD information. see what types we can handle

 183          $gd_info = function_exists('gd_info') ? gd_info() : $this->_gd_info();
 184          preg_match("/\A[\D]*([\d+\.]*)[\D]*\Z/", $gd_info['GD Version'], $matches);
 185          list($this->_gd_version_string, $this->_gd_version_number) = $matches;
 186          $this->_gd_version = substr($this->_gd_version_number, 0, strpos($this->_gd_version_number, '.'));
 187          if ($this->_gd_version >= 2) {
 188              $this->_imagecreatefunction = 'imagecreatetruecolor';
 189              $this->_resize_function = 'imagecopyresampled';
 190          } else {
 191              $this->_imagecreatefunction = 'imagecreate';
 192              $this->_resize_function = 'imagecopyresized';
 193          }
 194                          
 195          $this->_gd_ttf = $gd_info['FreeType Support'];
 196          $this->_gd_ps = $gd_info['T1Lib Support'];
 197          if ($gd_info['GIF Read Support']) {
 198              $this->_types[1]['supported'] = 1;
 199              if ($gd_info['GIF Create Support']) {
 200                  $this->_types[1]['supported'] = 2;
 201              }
 202          }
 203          if ($gd_info['JPG Support']) {
 204              $this->_types[2]['supported'] = 2;
 205          }
 206          if ($gd_info['PNG Support']) {
 207              $this->_types[3]['supported'] = 2;
 208          }
 209          
 210          //load or create main image

 211          if ($argc == 0) {
 212              return true;
 213          } else {
 214              if ($this->_addImage($argc, $args)) {
 215                  foreach ($this->_img['operator'] as $key => $value) {
 216                      $this->_img['main'][$key] = $value;
 217                  }
 218                  $this->_img['main']['output_type'] = $this->_img['main']['type'];
 219                  unset($this->_img['operator']);
 220                  return true;
 221              } else {
 222                  trigger_error($this->_error_prefix . 'No appropriate constructor found.', E_USER_ERROR);
 223                  return null;
 224              }
 225          }
 226      }
 227  
 228      /**

 229       * Returns an assocative array with information about the image features of this server

 230       *

 231       * Array values:

 232       * <ul>

 233       * <li>'gd_version' -> what GD version is installed on this server (e.g. 2.0)</li>

 234       * <li>'gif' -> 0 = not supported, 1 = reading is supported, 2 = creating is supported</li>

 235       * <li>'jpg' -> 0 = not supported, 1 = reading is supported, 2 = creating is supported</li>

 236       * <li>'png' -> 0 = not supported, 1 = reading is supported, 2 = creating is supported</li>

 237       * <li>'ttf' -> TTF text creation. true = supported, false = not supported

 238       * </ul>

 239       *

 240       * @return array

 241       */ 
 242  	function getServerFeatures() {
 243          $features = array();
 244          $features['gd_version'] = $this->_gd_version_number;
 245          $features['gif'] = $this->_types[1]['supported'];
 246          $features['jpg'] = $this->_types[2]['supported'];
 247          $features['png'] = $this->_types[3]['supported'];
 248          $features['ttf'] = $this->_gd_ttf;
 249          return $features;
 250      }
 251  
 252      /**

 253       * Flush all image resources and init a new one

 254       *

 255       * Parameter:<br>

 256       * <i>string</i> <b>$file</b> imagefile to load<br>

 257       * Or:<br>

 258       * <i>integer</i> <b>$width</b> imagewidth of new image to be created<br>

 259       * <i>integer</i> <b>$height</b> imageheight of new image to be created<br>

 260       * <i>string</i> <b>$fillcolor</b> optional fill the new image with this color (hexformat, e.g. '#FF0000')<br>

 261       */ 
 262  	function newImage() {
 263          $args = func_get_args();
 264          $argc = func_num_args();
 265          
 266          if ($this->_addImage($argc, $args)) {
 267              foreach ($this->_img['operator'] as $key => $value) {
 268                  $this->_img['main'][$key] = $value;
 269              }
 270              $this->_img['main']['output_type'] = $this->_img['main']['type'];
 271              unset($this->_img['operator']);
 272              return true;
 273          } else {
 274              trigger_error($this->_error_prefix . 'No appropriate constructor found.', E_USER_ERROR);
 275              return null;
 276          }
 277      }
 278  
 279      /**

 280       * Reimplements the original PHP {@link gd_info()} function for older PHP versions

 281       * 

 282       * @access private

 283       * @return array associative array with info about the GD library of the server

 284       */ 
 285  	function _gd_info() {
 286          $array = array(
 287              "GD Version" => "",
 288              "FreeType Support" => false,
 289              "FreeType Linkage" => "",
 290              "T1Lib Support" => false,
 291              "GIF Read Support" => false,
 292              "GIF Create Support" => false,
 293              "JPG Support" => false,
 294              "PNG Support" => false,
 295              "WBMP Support" => false,
 296              "XBM Support" => false
 297          );
 298          
 299          $gif_support = 0;
 300          ob_start();
 301          eval("phpinfo();");
 302          $info = ob_get_contents();
 303          ob_end_clean();
 304        
 305          foreach(explode("\n", $info) as $line) {
 306              if(strpos($line, "GD Version") !== false)
 307                  $array["GD Version"] = trim(str_replace("GD Version", "", strip_tags($line)));
 308              if(strpos($line, "FreeType Support") !== false)
 309                  $array["FreeType Support"] = trim(str_replace("FreeType Support", "", strip_tags($line)));
 310              if(strpos($line, "FreeType Linkage") !== false)
 311                  $array["FreeType Linkage"] = trim(str_replace("FreeType Linkage", "", strip_tags($line)));
 312              if(strpos($line, "T1Lib Support") !== false)
 313                  $array["T1Lib Support"] = trim(str_replace("T1Lib Support", "", strip_tags($line)));
 314              if(strpos($line, "GIF Read Support") !== false)
 315                  $array["GIF Read Support"] = trim(str_replace("GIF Read Support", "", strip_tags($line)));
 316              if(strpos($line, "GIF Create Support") !== false)
 317                  $array["GIF Create Support"] = trim(str_replace("GIF Create Support", "", strip_tags($line)));
 318              if(strpos($line, "GIF Support") !== false)
 319                  $gif_support = trim(str_replace("GIF Support", "", strip_tags($line)));
 320              if(strpos($line, "JPG Support") !== false)
 321                  $array["JPG Support"] = trim(str_replace("JPG Support", "", strip_tags($line)));
 322              if(strpos($line, "PNG Support") !== false)
 323                  $array["PNG Support"] = trim(str_replace("PNG Support", "", strip_tags($line)));
 324              if(strpos($line, "WBMP Support") !== false)
 325                  $array["WBMP Support"] = trim(str_replace("WBMP Support", "", strip_tags($line)));
 326              if(strpos($line, "XBM Support") !== false)
 327                  $array["XBM Support"] = trim(str_replace("XBM Support", "", strip_tags($line)));
 328          }
 329          
 330          if($gif_support === "enabled") {
 331              $array["GIF Read Support"] = true;
 332              $array["GIF Create Support"] = true;
 333          }
 334  
 335          if($array["FreeType Support"] === "enabled") {
 336              $array["FreeType Support"] = true;
 337          }
 338   
 339          if($array["T1Lib Support"] === "enabled") {
 340              $array["T1Lib Support"] = true;
 341          }
 342         
 343          if($array["GIF Read Support"] === "enabled") {
 344              $array["GIF Read Support"] = true;
 345          }
 346   
 347          if($array["GIF Create Support"] === "enabled") {
 348              $array["GIF Create Support"] = true;
 349          }
 350  
 351          if($array["JPG Support"] === "enabled") {
 352              $array["JPG Support"] = true;
 353          }
 354              
 355          if($array["PNG Support"] === "enabled") {
 356              $array["PNG Support"] = true;
 357          }
 358              
 359          if($array["WBMP Support"] === "enabled") {
 360              $array["WBMP Support"] = true;
 361          }
 362              
 363          if($array["XBM Support"] === "enabled") {
 364              $array["XBM Support"] = true;
 365          }
 366  
 367          return $array;
 368      }
 369  
 370      /**

 371       * Convert a color defined in hexvalues to the PHP color format

 372       * 

 373       * @access private

 374       * @param string $hex color value in hexformat (e.g. '#FF0000')

 375       * @return integer color value in PHP format

 376       */ 
 377  	function _hexToPHPColor($hex) {
 378          $length = strlen($hex);
 379          $dr = hexdec(substr($hex, $length - 6, 2));
 380          $dg = hexdec(substr($hex, $length - 4, 2));
 381          $db = hexdec(substr($hex, $length - 2, 2));
 382          $color = ($dr << 16) + ($dg << 8) + $db;
 383          return $color;
 384      }
 385      
 386      /**

 387       * Convert a color defined in hexvalues to corresponding dezimal values

 388       * 

 389       * @access private

 390       * @param string $hex color value in hexformat (e.g. '#FF0000')

 391       * @return array associative array with color values in dezimal format (fields: 'red', 'green', 'blue')

 392       */ 
 393  	function _hexToDecColor($hex) {
 394          $length = strlen($hex);
 395          $color['red'] = hexdec(substr($hex, $length - 6, 2));
 396          $color['green'] = hexdec(substr($hex, $length - 4, 2));
 397          $color['blue'] = hexdec(substr($hex, $length - 2, 2));
 398          return $color;
 399      }
 400  
 401      /**

 402       * Generate a new image resource based on the given parameters

 403       *

 404       * Parameter:

 405       * <i>string</i> <b>$file</b> imagefile to load<br>

 406       * Or:<br>

 407       * <i>integer</i> <b>$width</b> imagewidth of new image to be created<br>

 408       * <i>integer</i> <b>$height</b> imageheight of new image to be created<br>

 409       * <i>string</i> <b>$fillcolor</b> optional fill the new image with this color (hexformat, e.g. '#FF0000')<br>

 410       *

 411       * @access private

 412       */
 413  	function _addImage($argc, $args) {
 414          if (($argc == 2 || $argc == 3) && is_int($args[0]) && is_int($args[1]) && (is_string($args[2]) || !isset($args[2]))) {
 415              //neues leeres bild mit width und height (fillcolor optional)

 416              $this->_img['operator']['width'] = $args[0];
 417              $this->_img['operator']['height'] = $args[1];
 418              ($this->_img['operator']['width'] >= $this->_img['operator']['height']) ? ($this->_img['operator']['bias'] = IMAGE_TOOLBOX_BIAS_HORIZONTAL) : ($this->_img['operator']['bias'] = IMAGE_TOOLBOX_BIAS_VERTICAL);
 419              $this->_img['operator']['aspectratio'] = $this->_img['operator']['width'] / $this->_img['operator']['height'];
 420              $this->_img['operator']['indexedcolors'] = 0;
 421              $functionname = $this->_imagecreatefunction;
 422              $this->_img['operator']['resource'] = $functionname($this->_img['operator']['width'], $this->_img['operator']['height']);
 423              // set default type jpg.

 424              $this->_img['operator']['type'] = 2;
 425              if (isset($args[2]) && is_string($args[2])) {
 426                  //neues bild mit farbe fllen

 427                  $fillcolor = $this->_hexToPHPColor($args[2]);
 428                  imagefill($this->_img['operator']['resource'], 0, 0, $fillcolor);
 429                  $this->_img['operator']['color'] = $fillcolor;
 430              } else {
 431                  $this->_img['operator']['color'] = 0;
 432              }
 433          } elseif ($argc == 1 && is_string($args[0])) {
 434              //bild aus datei laden. width und height original grsse

 435              $this->_img['operator'] = $this->_loadFile($args[0]);
 436              $this->_img['operator']['indexedcolors'] = imagecolorstotal($this->_img['operator']['resource']);
 437              $this->_img['operator']['color'] = -1;
 438          } else {
 439              return false;
 440          }
 441          return true;
 442      }
 443  
 444      /**

 445       * Loads a image file

 446       *

 447       * @access private

 448       * @param string $filename imagefile to load

 449       * @return array associative array with the loaded filedata

 450       */
 451  	function _loadFile($filename) {
 452          if (file_exists($filename)) {
 453              $info = getimagesize($filename);
 454              $filedata['width'] = $info[0];
 455              $filedata['height'] = $info[1];
 456              ($filedata['width'] >= $filedata['height']) ? ($filedata['bias'] = IMAGE_TOOLBOX_BIAS_HORIZONTAL) : ($filedata['bias'] = IMAGE_TOOLBOX_BIAS_VERTICAL);
 457                 $filedata['aspectratio'] = $filedata['width'] / $filedata['height'];
 458              $filedata['type'] = $info[2];
 459  
 460              if ($this->_types[$filedata['type']]['supported'] < 1) {
 461                  trigger_error($this->_error_prefix . 'Imagetype ('.$this->_types[$filedata['type']]['ext'].') not supported for reading.', E_USER_ERROR);
 462                  return null;
 463              }
 464              switch ($filedata['type']) {
 465                  case 1:
 466                      $dummy = imagecreatefromgif($filename);
 467                      $functionname = $this->_imagecreatefunction;
 468                      $filedata['resource'] = $functionname($filedata['width'], $filedata['height']);
 469                      imagecopy($filedata['resource'], $dummy, 0, 0, 0, 0, $filedata['width'], $filedata['height']);
 470                      imagedestroy($dummy);
 471                      break;
 472                      
 473                  case 2:
 474                      $filedata['resource'] = imagecreatefromjpeg($filename);
 475                      break;
 476                      
 477                  case 3:
 478                      $dummy = imagecreatefrompng($filename);
 479                      if (imagecolorstotal($dummy) != 0) {
 480                          $functionname = $this->_imagecreatefunction;
 481                          $filedata['resource'] = $functionname($filedata['width'], $filedata['height']);
 482                          imagecopy($filedata['resource'], $dummy, 0, 0, 0, 0, $filedata['width'], $filedata['height']);
 483                      } else {
 484                          $filedata['resource'] = $dummy;
 485                      }
 486                      unset($dummy);
 487                      break;
 488                      
 489                  default:
 490                      trigger_error($this->_error_prefix . 'Imagetype not supported.', E_USER_ERROR);
 491                      return null;
 492              }
 493              return $filedata;
 494          } else {
 495              trigger_error($this->_error_prefix . 'Imagefile (' . $filename . ') does not exist.', E_USER_ERROR);
 496              return null;
 497          }
 498      }
 499      
 500      /**

 501       * Output a image to the browser

 502       *

 503       * $output_type can be one of the following:<br>

 504       * <ul>

 505       * <li>'gif' -> gif image (if supported) (8-bit indexed colors)</li>

 506       * <li>'png' -> png image (if supported) (truecolor)</li>

 507       * <li>'png8' -> png image (if supported) (8-bit indexed colors)</li>

 508       * <li>'jpg' -> jpeg image (if supported) (truecolor)</li>

 509       * </ul>

 510       * (default: same as original)

 511       *

 512       * $dither:<br>

 513       * If this is true than dither is used on the conversion from truecolor to 8-bit indexed imageformats (png8, gif)<br>

 514       * (default = false)

 515       *

 516       * @param string|integer $output_type type of outputted image

 517       * @param integer $output_quality jpeg quality of outputted image (default: IMAGE_TOOLBOX_DEFAULT_JPEG_QUALITY)

 518       * @param bool $dither use dither

 519       * @return bool true on success, otherwise false

 520       */
 521  	function output($output_type = false, $output_quality = false, $dither = false) {
 522          if ($output_type === false) {
 523              $output_type = $this->_img['main']['output_type'];
 524          }
 525          switch ($output_type) {
 526              case 1:
 527              case 'gif':
 528              case 'GIF':
 529                  if ($this->_types[1]['supported'] < 2) {
 530                      trigger_error($this->_error_prefix . 'Imagetype ('.$this->_types[$output_type]['ext'].') not supported for creating/writing.', E_USER_ERROR);
 531                      return null;
 532                  }
 533                  header ('Content-type: ' . $this->_types[$output_type]['mime']);
 534                  if ($this->_gd_version >= 2) {
 535                      if ($this->_img['main']['indexedcolors'] == 0) {
 536                          $dummy = imagecreatetruecolor($this->_img['main']['width'], $this->_img['main']['height']);
 537                          imagecopy($dummy, $this->_img['main']['resource'], 0, 0, 0, 0, $this->_img['main']['width'], $this->_img['main']['height']);
 538                          if ($output_quality === false) {
 539                              $output_quality = IMAGE_TOOLBOX_DEFAULT_8BIT_COLORS;
 540                          }
 541                          imagetruecolortopalette($dummy, $dither, $output_quality);
 542                      }
 543                      imagegif($dummy);
 544                      imagedestroy($dummy);
 545                  }
 546                  else {
 547                      imagegif($this->_img['main']['resource']);
 548                  }
 549                  break;
 550              
 551              case 2:
 552              case '2':
 553              case 'jpg':
 554              case 'jpeg':
 555              case 'JPG':
 556              case 'JPEG':
 557                  if ($this->_types[2]['supported'] < 2) {
 558                      trigger_error($this->_error_prefix . 'Imagetype ('.$this->_types[$output_type]['ext'].') not supported for creating/writing.', E_USER_ERROR);
 559                      return null;
 560                  }
 561                  header ('Content-type: ' . $this->_types[$output_type]['mime']);
 562                  if ($output_quality === false) {
 563                      $output_quality = IMAGE_TOOLBOX_DEFAULT_JPEG_QUALITY;
 564                  }
 565                  imagejpeg($this->_img['main']['resource'], '', $output_quality);
 566                  break;
 567                  
 568              case 3:
 569              case '3':
 570              case 'png':
 571              case 'PNG':
 572              case 'png24':
 573              case 'PNG24':
 574                  if ($this->_types[3]['supported'] < 2) {
 575                      trigger_error($this->_error_prefix . 'Imagetype ('.$this->_types[$output_type]['ext'].') not supported for creating/writing.', E_USER_ERROR);
 576                      return null;
 577                  }
 578                  header ('Content-type: ' . $this->_types[$output_type]['mime']);
 579                  imagepng($this->_img['main']['resource']);
 580                  break;
 581                  
 582              case 4:
 583              case '4':
 584              case 'png8':
 585              case 'PNG8':
 586                  if ($this->_types[3]['supported'] < 2) {
 587                      trigger_error($this->_error_prefix . 'Imagetype ('.$this->_types[$output_type]['ext'].') not supported for creating/writing.', E_USER_ERROR);
 588                      return null;
 589                  }
 590                  header ('Content-type: ' . $this->_types[$output_type]['mime']);
 591                  if ($this->_gd_version >= 2) {
 592                      if ($this->_img['main']['indexedcolors'] == 0) {
 593                          $dummy = imagecreatetruecolor($this->_img['main']['width'], $this->_img['main']['height']);
 594                          imagecopy($dummy, $this->_img['main']['resource'], 0, 0, 0, 0, $this->_img['main']['width'], $this->_img['main']['height']);
 595                          if ($output_quality === false) {
 596                              $output_quality = IMAGE_TOOLBOX_DEFAULT_8BIT_COLORS;
 597                          }
 598                          imagetruecolortopalette($dummy, $dither, $output_quality);
 599                      }
 600                      imagepng($dummy);
 601                      imagedestroy($dummy);
 602                  }
 603                  else {
 604                      imagepng($this->_img['main']['resource']);
 605                  }
 606                  break;
 607                  
 608              default:
 609                  trigger_error($this->_error_prefix . 'Output-Imagetype not supported.', E_USER_ERROR);
 610                  return null;
 611          }
 612          return true;
 613      }
 614      
 615      /**

 616       * Save a image to disk

 617       *

 618       * $output_type can be one of the following:<br>

 619       * <ul>

 620       * <li>'gif' -> gif image (if supported) (8-bit indexed colors)</li>

 621       * <li>'png' -> png image (if supported) (truecolor)</li>

 622       * <li>'png8' -> png image (if supported) (8-bit indexed colors)</li>

 623       * <li>'jpg' -> jpeg image (if supported) (truecolor)</li>

 624       * </ul>

 625       * (default: same as original)

 626       *

 627       * $dither:<br>

 628       * If this is true than dither is used on the conversion from truecolor to 8-bit indexed imageformats (png8, gif)<br>

 629       * (default = false)

 630       *

 631       * @param string $filename filename of saved image

 632       * @param string|integer $output_type type of saved image

 633       * @param integer $output_quality jpeg quality of saved image (default: IMAGE_TOOLBOX_DEFAULT_JPEG_QUALITY)

 634       * @param bool $dither use dither

 635       * @return bool true on success, otherwise false

 636       */
 637  	function save($filename, $output_type = false, $output_quality = false, $dither = false) {
 638          if ($output_type === false) {
 639              $output_type = $this->_img['main']['output_type'];
 640          }
 641          switch ($output_type) {
 642              case 1:
 643              case 'gif':
 644              case 'GIF':
 645                  if ($this->_types[1]['supported'] < 2) {
 646                      trigger_error($this->_error_prefix . 'Imagetype ('.$this->_types[$output_type]['ext'].') not supported for creating/writing.', E_USER_ERROR);
 647                      return null;
 648                  }
 649                  if ($this->_gd_version >= 2) {
 650                      if ($this->_img['main']['indexedcolors'] == 0) {
 651                          $dummy = imagecreatetruecolor($this->_img['main']['width'], $this->_img['main']['height']);
 652                          imagecopy($dummy, $this->_img['main']['resource'], 0, 0, 0, 0, $this->_img['main']['width'], $this->_img['main']['height']);
 653                          if ($output_quality === false) {
 654                              $output_quality = IMAGE_TOOLBOX_DEFAULT_8BIT_COLORS;
 655                          }
 656                          imagetruecolortopalette($dummy, $dither, $output_quality);
 657                      }
 658                      imagegif($dummy, $filename);
 659                      imagedestroy($dummy);
 660                  }
 661                  else {
 662                      imagegif($this->_img['main']['resource']);
 663                  }
 664                  break;
 665              
 666              case 2:
 667              case '2':
 668              case 'jpg':
 669              case 'jpeg':
 670              case 'JPG':
 671              case 'JPEG':
 672                  if ($this->_types[2]['supported'] < 2) {
 673                      trigger_error($this->_error_prefix . 'Imagetype ('.$this->_types[$output_type]['ext'].') not supported for creating/writing.', E_USER_ERROR);
 674                      return null;
 675                  }
 676                  if ($output_quality === false) {
 677                      $output_quality = IMAGE_TOOLBOX_DEFAULT_JPEG_QUALITY;
 678                  }
 679                  imagejpeg($this->_img['main']['resource'], $filename, $output_quality);
 680                  break;
 681                  
 682              case 3:
 683              case '3':
 684              case 'png':
 685              case 'PNG':
 686              case 'png24':
 687              case 'PNG24':
 688                  if ($this->_types[3]['supported'] < 2) {
 689                      trigger_error($this->_error_prefix . 'Imagetype ('.$this->_types[$output_type]['ext'].') not supported for creating/writing.', E_USER_ERROR);
 690                      return null;
 691                  }
 692                  header ('Content-type: ' . $this->_types[$output_type]['mime']);
 693                  imagepng($this->_img['main']['resource'], $filename);
 694                  break;
 695                  
 696              case 4:
 697              case '4':
 698              case 'png8':
 699              case 'PNG8':
 700                  if ($this->_types[3]['supported'] < 2) {
 701                      trigger_error($this->_error_prefix . 'Imagetype ('.$this->_types[$output_type]['ext'].') not supported for creating/writing.', E_USER_ERROR);
 702                      return null;
 703                  }
 704                  if ($this->_gd_version >= 2) {
 705                      if ($this->_img['main']['indexedcolors'] == 0) {
 706                          $dummy = imagecreatetruecolor($this->_img['main']['width'], $this->_img['main']['height']);
 707                          imagecopy($dummy, $this->_img['main']['resource'], 0, 0, 0, 0, $this->_img['main']['width'], $this->_img['main']['height']);
 708                          if ($output_quality === false) {
 709                              $output_quality = IMAGE_TOOLBOX_DEFAULT_8BIT_COLORS;
 710                          }
 711                          imagetruecolortopalette($dummy, $dither, $output_quality);
 712                      }
 713                      imagepng($dummy, $filename);
 714                      imagedestroy($dummy);
 715                  }
 716                  else {
 717                      imagepng($this->_img['main']['resource'], $filename);
 718                  }
 719                  break;
 720                  
 721              default:
 722                  trigger_error($this->_error_prefix . 'Output-Imagetype not supported.', E_USER_ERROR);
 723                  return null;
 724          }
 725          return true;
 726      }
 727      
 728      /**

 729       * Sets the resize method of choice

 730       * 

 731       * $method can be one of the following:<br>

 732       * <ul>

 733       * <li>'resize' -> supported by every version of GD (fast but ugly resize of image)</li>

 734       * <li>'resample' -> only supported by GD version >= 2.0 (slower but antialiased resize of image)</li>

 735       * <li>'workaround' -> supported by every version of GD (workaround function for bicubic resizing, downsizing, VERY slow!, taken from php.net comments)</li>

 736       * <li>'workaround2' -> supported by every version of GD (alternative workaround function for bicubic resizing, down- and upsizing, VERY VERY slow!, taken from php.net comments)</li>

 737       * </ul>

 738       *

 739       * @param string|integer $method resize method

 740       * @return bool true on success, otherwise false

 741       */
 742  	function setResizeMethod($method) {
 743          switch ($method) {
 744              case 1:
 745              case '1':
 746              case 'resize':
 747                  $this->_resize_function = 'imagecopyresized';
 748                  break;
 749                  
 750              case 2:
 751              case '2':
 752              case 'resample':
 753                  if (!function_exists('imagecopyresampled')) {
 754                      // no error message. just return false.

 755                      return null;
 756                  }
 757                  $this->_resize_function = 'imagecopyresampled';
 758                  break;
 759                  
 760              case 3:
 761              case '3':
 762              case 'resample_workaround':
 763              case 'workaround':
 764              case 'bicubic':
 765                  $this->_resize_function = '$this->_imageCopyResampledWorkaround';
 766                  break;
 767                  
 768              case 4:
 769              case '4':
 770              case 'resample_workaround2':
 771              case 'workaround2':
 772              case 'bicubic2':
 773                  $this->_resize_function = '$this->_imageCopyResampledWorkaround2';
 774                  break;
 775                  
 776              default:
 777                  trigger_error($this->_error_prefix . 'Resizemethod not supported.', E_USER_ERROR);
 778                  return null;
 779          }
 780          return true;
 781      }
 782      
 783      /**

 784       * Resize the current image

 785       * 

 786       * if $width = 0 the new width will be calculated from the $height value preserving the correct aspectratio.<br>

 787       *

 788       * if $height = 0 the new height will be calculated from the $width value preserving the correct aspectratio.<br>

 789       *

 790       * $mode can be one of the following:<br>

 791       * <ul>

 792       * <li>0 -> image will be resized to the new output size, regardless of the original aspectratio. (default)</li>

 793       * <li>1 -> image will be cropped if necessary to preserve the aspectratio and avoid image distortions.</li>

 794       * <li>2 -> image will be resized preserving its original aspectratio. differences to the new outputsize will be filled with $bgcolor</li>

 795       * </ul>

 796       *

 797       * if $autorotate is set to true the given $width and $height values may "change place" if the given image bias is different from the original one.<br>

 798       * if either $width or $height is 0, the new size will be applied to either the new width or the new height based on the bias value of the original image.<br>

 799       * (default = false)

 800       *

 801       * @param integer $width new width of image

 802       * @param integer $height new height of image

 803       * @param integer $mode resize mode

 804       * @param bool $autorotate use autorotating

 805       * @param string $bgcolor background fillcolor (hexformat, e.g. '#FF0000')

 806       * @return bool true on success, otherwise false

 807       */
 808  	function newOutputSize($width, $height, $mode = 0, $autorotate = false, $bgcolor = '#000000') {
 809          if ($width > 0 && $height > 0 && is_int($width) && is_int($height)) {
 810              //ignore aspectratio

 811              if (!$mode) {
 812                  //do not crop to get correct aspectratio

 813                  ($width >= $height) ? ($this->_img['target']['bias'] = IMAGE_TOOLBOX_BIAS_HORIZONTAL) : ($this->_img['target']['bias'] = IMAGE_TOOLBOX_BIAS_VERTICAL);
 814                  if ($this->_img['main']['bias'] == $this->_img['target']['bias'] || !$autorotate) {
 815                      $this->_img['target']['width'] = $width;
 816                      $this->_img['target']['height'] = $height;
 817                  } else {
 818                      $this->_img['target']['width'] = $height;
 819                      $this->_img['target']['height'] = $width;
 820                  }
 821                  $this->_img['target']['aspectratio'] = $this->_img['target']['width'] / $this->_img['target']['height'];
 822                  
 823                  $cpy_w = $this->_img['main']['width'];
 824                  $cpy_h = $this->_img['main']['height'];
 825                  $cpy_w_offset = 0;
 826                  $cpy_h_offset = 0;
 827              } elseif ($mode == 1) {
 828                  //crop to get correct aspectratio

 829                  ($width >= $height) ? ($this->_img['target']['bias'] = IMAGE_TOOLBOX_BIAS_HORIZONTAL) : ($this->_img['target']['bias'] = IMAGE_TOOLBOX_BIAS_VERTICAL);
 830                  if ($this->_img['main']['bias'] == $this->_img['target']['bias'] || !$autorotate) {
 831                      $this->_img['target']['width'] = $width;
 832                      $this->_img['target']['height'] = $height;
 833                  } else {
 834                      $this->_img['target']['width'] = $height;
 835                      $this->_img['target']['height'] = $width;
 836                  }
 837                  $this->_img['target']['aspectratio'] = $this->_img['target']['width'] / $this->_img['target']['height'];
 838                  
 839                  if ($this->_img['main']['width'] / $this->_img['target']['width'] >= $this->_img['main']['height'] / $this->_img['target']['height']) {
 840                      $cpy_h = $this->_img['main']['height'];
 841                      $cpy_w = (integer) $this->_img['main']['height'] * $this->_img['target']['aspectratio'];
 842                      $cpy_w_offset = (integer) ($this->_img['main']['width'] - $cpy_w) / 2;
 843                      $cpy_h_offset = 0;
 844                  } else {
 845                      $cpy_w = $this->_img['main']['width'];
 846                      $cpy_h = (integer) $this->_img['main']['width'] / $this->_img['target']['aspectratio'];
 847                      $cpy_h_offset = (integer) ($this->_img['main']['height'] - $cpy_h) / 2;
 848                      $cpy_w_offset = 0;
 849                  }
 850              }
 851              elseif ($mode == 2) {
 852                  //fill remaining background with a color to keep aspectratio

 853                  $final_aspectratio = $width / $height;
 854                  if ($final_aspectratio < $this->_img['main']['aspectratio']) {
 855                      $this->_img['target']['width'] = $width;
 856                      $this->_img['target']['height'] = (integer) $width / $this->_img['main']['aspectratio'];
 857                      $cpy_w_offset2 = 0;
 858                      $cpy_h_offset2 = (integer) (($height - $this->_img['target']['height']) / 2);
 859                  }
 860                  else {
 861                      $this->_img['target']['height'] = $height;
 862                      $this->_img['target']['width'] = (integer) $height * $this->_img['main']['aspectratio'];
 863                      $cpy_h_offset2 = 0;
 864                      $cpy_w_offset2 = (integer) (($width - $this->_img['target']['width']) / 2);
 865                  }
 866                  $this->_img['target']['aspectratio'] = $this->_img['main']['aspectratio'];
 867                  $cpy_w = $this->_img['main']['width'];
 868                  $cpy_h = $this->_img['main']['height'];
 869                  $cpy_w_offset = 0;
 870                  $cpy_h_offset = 0;
 871              }
 872          } elseif (($width == 0 && $height > 0) || ($width > 0 && $height == 0) && is_int($width) && is_int($height)) {
 873              //keep aspectratio

 874              if ($autorotate == true) {
 875                  if ($this->_img['main']['bias'] == IMAGE_TOOLBOX_BIAS_HORIZONTAL && $width > 0) {
 876                      $height = $width;
 877                      $width = 0;
 878                  } elseif ($this->_img['main']['bias'] == IMAGE_TOOLBOX_BIAS_VERTICAL && $height > 0) {
 879                      $width = $height;
 880                      $height = 0;
 881                  }
 882              }
 883              ($width >= $height) ? ($this->_img['target']['bias'] = IMAGE_TOOLBOX_BIAS_HORIZONTAL) : ($this->_img['target']['bias'] = IMAGE_TOOLBOX_BIAS_VERTICAL);
 884              if ($width != 0) {
 885                  $this->_img['target']['width'] = $width;
 886                  $this->_img['target']['height'] = (integer) $width / $this->_img['main']['aspectratio'];
 887              } else {
 888                  $this->_img['target']['height'] = $height;
 889                  $this->_img['target']['width'] = (integer) $height * $this->_img['main']['aspectratio'];
 890              }
 891              $this->_img['target']['aspectratio'] = $this->_img['main']['aspectratio'];
 892              
 893              $cpy_w = $this->_img['main']['width'];
 894              $cpy_h = $this->_img['main']['height'];
 895              $cpy_w_offset = 0;
 896              $cpy_h_offset = 0;
 897          } else {
 898              trigger_error($this->_error_prefix . 'Outputwidth and -height must be integers greater zero.', E_USER_ERROR);
 899              return null;
 900          }
 901          
 902          //create resized picture

 903          $functionname = $this->_imagecreatefunction;
 904          $dummy = $functionname($this->_img['target']['width'] + 1, $this->_img['target']['height'] + 1);
 905          eval($this->_resize_function . '($dummy, $this->_img["main"]["resource"], 0, 0, $cpy_w_offset, $cpy_h_offset, $this->_img["target"]["width"], $this->_img["target"]["height"], $cpy_w, $cpy_h);');
 906          if ($mode == 2) {
 907              $this->_img['target']['resource'] = $functionname($width, $height);
 908              $fillcolor = $this->_hexToPHPColor($bgcolor);
 909              imagefill($this->_img['target']['resource'], 0, 0, $fillcolor);
 910          } else {
 911              $this->_img['target']['resource'] = $functionname($this->_img['target']['width'], $this->_img['target']['height']);
 912              $cpy_w_offset2 = 0;
 913              $cpy_h_offset2 = 0;
 914          }
 915          imagecopy($this->_img['target']['resource'], $dummy, $cpy_w_offset2, $cpy_h_offset2, 0, 0, $this->_img['target']['width'], $this->_img['target']['height']);
 916          imagedestroy($dummy);
 917          
 918          if ($mode == 2) {
 919              $this->_img['target']['width'] = $width;
 920              $this->_img['target']['height'] = $height;
 921          }
 922          //update _img['main'] with new data

 923          foreach ($this->_img['target'] as $key => $value) {
 924              $this->_img['main'][$key] = $value;
 925          }
 926          unset ($this->_img['target']);
 927          
 928          return true;
 929      }
 930  
 931      /**

 932       * Adds a new image resource based on the given parameters.

 933       *

 934       * It does not overwrite the existing image resource.<br>

 935       * Instead it is used to load a second image to merge with the existing image.

 936       *

 937       * Parameter:<br>

 938       * <i>string</i> <b>$file</b> imagefile to load<br>

 939       * Or:<br>

 940       * <i>integer</i> <b>$width</b> imagewidth of new image to be created<br>

 941       * <i>integer</i> <b>$height</b> imageheight of new image to be created<br>

 942       * <i>string</i> <b>$fillcolor</b> optional fill the new image with this color (hexformat, e.g. '#FF0000')<br>

 943       */    
 944  	function addImage() {
 945          $args = func_get_args(); 
 946          $argc = func_num_args();
 947          
 948          if ($this->_addImage($argc, $args)) {
 949              return true;
 950          } else {
 951              trigger_error($this->_error_prefix . 'failed to add image.', E_USER_ERROR);
 952              return false;
 953          }
 954      }
 955      
 956      /**

 957       * Blend two images.

 958       *

 959       * Original image and the image loaded with {@link addImage() addImage}<br>

 960       * NOTE: This operation can take very long and is not intended for realtime use.

 961       * (but of course depends on the power of your server :) )

 962       *

 963       * IMPORTANT: {@link imagecopymerge() imagecopymerged} doesn't work with PHP 4.3.2. Bug ID: {@link http://bugs.php.net/bug.php?id=24816 24816}<br>

 964       *

 965       * $x:<br>

 966       * negative values are possible.<br>

 967       * You can also use the following keywords ('left', 'center' or 'middle', 'right').<br>

 968       * Additionally you can specify an offset in pixel with the keywords like this 'left +10'.<br>

 969       * (default = 0)

 970       *

 971       * $y:<br>

 972       * negative values are possible.<br>

 973       * You can also use the following keywords ('top', 'center' or 'middle', 'bottom').<br>

 974       * Additionally you can specify an offset in pixel with the keywords like this 'bottom -10'.<br>

 975       * (default = 0)

 976       *

 977       * Possible values for $mode:

 978       * <ul>

 979       *  <li>IMAGE_TOOLBOX_BLEND_COPY</li>

 980       *  <li>IMAGE_TOOLBOX_BLEND_MULTIPLY</li>

 981       *  <li>IMAGE_TOOLBOX_BLEND_SCREEN</li>

 982       *  <li>IMAGE_TOOLBOX_BLEND_DIFFERENCE</li>

 983       *  <li>IMAGE_TOOLBOX_BLEND_EXCLUSION</li>

 984       *  <li>IMAGE_TOOLBOX_BLEND_OVERLAY</li>

 985       * </ul>

 986       *

 987       * $percent:<br>

 988       * alpha value in percent of blend effect (0 - 100)<br>

 989       * (default = 100)

 990       *

 991       * @param string|integer $x Horizontal position of second image. 

 992       * @param integer $y Vertical position of second image. negative values are possible.

 993       * @param integer $mode blend mode.

 994       * @param integer $percent alpha value

 995       */    
 996  	function blend($x = 0, $y = 0, $mode = IMAGE_TOOLBOX_BLEND_COPY, $percent = 100) {
 997          if (is_string($x) || is_string($y)) {
 998              list($xalign, $xalign_offset) = explode(" ", $x);
 999              list($yalign, $yalign_offset) = explode(" ", $y);
1000          }
1001          if (is_string($x)) {
1002              switch ($xalign) {
1003                  case 'left':
1004                      $dst_x = 0 + $xalign_offset;
1005                      $src_x = 0;
1006                      $src_w = $this->_img['operator']['width'];
1007                      break;
1008                      
1009                  case 'right':
1010                      $dst_x = ($this->_img['main']['width'] - $this->_img['operator']['width']) + $xalign_offset;
1011                      $src_x = 0;
1012                      $src_w = $this->_img['operator']['width'];
1013                      break;
1014                      
1015                  case 'middle':
1016                  case 'center':
1017                      $dst_x = (($this->_img['main']['width'] / 2) - ($this->_img['operator']['width'] / 2)) + $yalign_offset;
1018                      $src_x = 0;
1019                      $src_w = $this->_img['operator']['width'];
1020                      break;
1021              }
1022          } else {
1023              if ($x >= 0) {
1024                  $dst_x = $x;
1025                  $src_x = 0;
1026                  $src_w = $this->_img['operator']['width'];
1027              } else {
1028                  $dst_x = 0;
1029                  $src_x = abs($x);
1030                  $src_w = $this->_img['operator']['width'] - $src_x;
1031              }
1032          }
1033          if (is_string($y)) {
1034              switch ($yalign) {
1035                  case 'top':
1036                      $dst_y = 0 + $yalign_offset;
1037                      $src_y = 0;
1038                      $src_h = $this->_img['operator']['height'];
1039                      break;
1040                      
1041                  case 'bottom':
1042                      $dst_y = ($this->_img['main']['height'] - $this->_img['operator']['height']) + $yalign_offset;
1043                      $src_y = 0;
1044                      $src_h = $this->_img['operator']['height'];
1045                      break;
1046                      
1047                  case 'middle':
1048                  case 'center':
1049                      $dst_y = (($this->_img['main']['height'] / 2) - ($this->_img['operator']['height'] / 2)) + $yalign_offset;
1050                      $src_y = 0;
1051                      $src_h = $this->_img['operator']['height'];
1052                      break;
1053              }
1054          } else {
1055              if ($y >= 0) {
1056                  $dst_y = $y;
1057                  $src_y = 0;
1058                  $src_h = $this->_img['operator']['height'];
1059              } else {
1060                  $dst_y = 0;
1061                  $src_y = abs($y);
1062                  $src_h = $this->_img['operator']['height'] - $src_y;
1063              }
1064          }
1065          $this->_imageBlend($mode, $dst_x, $dst_y, $src_x, $src_y, $src_w, $src_h, $percent);
1066          return true;
1067      }
1068      
1069      /**

1070       * Blend two images.

1071       *

1072       * @access private

1073       */    
1074  	function _imageBlend($mode, $dst_x, $dst_y, $src_x, $src_y, $src_w, $src_h, $percent) {
1075          if ($mode == IMAGE_TOOLBOX_BLEND_COPY) {
1076              if ($percent == 100) {
1077                  imagecopy($this->_img['main']['resource'], $this->_img['operator']['resource'], $dst_x, $dst_y, $src_x, $src_y, $src_w, $src_h);
1078              } else {
1079                  imagecopymerge($this->_img['main']['resource'], $this->_img['operator']['resource'], $dst_x, $dst_y, $src_x, $src_y, $src_w, $src_h, $percent);
1080              }
1081          } else {
1082              $functionname = $this->_imagecreatefunction;
1083              $dummy = $functionname($src_w, $src_h);
1084              for ($y=0; $y < $src_h; $y++) {
1085                  for ($x=0; $x < $src_w; $x++) {
1086                      $colorindex = imagecolorat($this->_img['main']['resource'], $dst_x + $x, $dst_y + $y);
1087                      $colorrgb1 = imagecolorsforindex($this->_img['main']['resource'], $colorindex);
1088                      $colorindex = imagecolorat($this->_img['operator']['resource'], $src_x + $x, $src_y + $y);
1089                      $colorrgb2 = imagecolorsforindex($this->_img['operator']['resource'], $colorindex);
1090                      $colorblend = $this->_calculateBlendvalue($mode, $colorrgb1, $colorrgb2);
1091                      $newcolor = imagecolorallocate($dummy, $colorblend['red'], $colorblend['green'], $colorblend['blue']);
1092                      imagesetpixel($dummy, $x, $y, $newcolor);
1093                  }
1094              }
1095          
1096              $this->_img['target']['resource'] = $functionname($this->_img['main']['width'], $this->_img['main']['height']);
1097              imagecopy($this->_img['target']['resource'], $this->_img['main']['resource'], 0, 0, 0, 0, $this->_img['main']['width'], $this->_img['main']['height']);
1098              imagecopymerge($this->_img['target']['resource'], $dummy, $dst_x, $dst_y, $src_x, $src_y, $src_w, $src_h, $percent);
1099                                      
1100              $this->_img['main']['resource'] = $this->_img['target']['resource'];
1101              unset($this->_img['target']);
1102          }
1103      }
1104      
1105      /**

1106       * Calculate blend values for given blend mode

1107       *

1108       * @access private

1109       */    
1110  	function _calculateBlendvalue($mode, $colorrgb1, $colorrgb2) {
1111          switch ($mode) {
1112              case IMAGE_TOOLBOX_BLEND_MULTIPLY:
1113                  $c['red'] = ($colorrgb1['red'] * $colorrgb2['red']) >> 8;
1114                  $c['green'] = ($colorrgb1['green'] * $colorrgb2['green']) >> 8;
1115                  $c['blue'] = ($colorrgb1['blue'] * $colorrgb2['blue']) >> 8;
1116                  break;
1117              
1118              case IMAGE_TOOLBOX_BLEND_SCREEN:
1119                  $c['red'] = 255 - ((255 - $colorrgb1['red']) * (255 - $colorrgb2['red']) >> 8);
1120                  $c['green'] = 255 - ((255 - $colorrgb1['green']) * (255 - $colorrgb2['green']) >> 8);
1121                  $c['blue'] = 255 - ((255 - $colorrgb1['blue']) * (255 - $colorrgb2['blue']) >> 8);
1122                  break;
1123              
1124              case IMAGE_TOOLBOX_BLEND_DIFFERENCE:
1125                  $c['red'] = abs($colorrgb1['red'] - $colorrgb2['red']);
1126                  $c['green'] = abs($colorrgb1['green'] - $colorrgb2['green']);
1127                  $c['blue'] = abs($colorrgb1['blue'] - $colorrgb2['blue']);
1128                  break;
1129              
1130              case IMAGE_TOOLBOX_BLEND_NEGATION:    
1131                  $c['red'] = 255 - abs(255 - $colorrgb1['red'] - $colorrgb2['red']);
1132                  $c['green'] = 255 - abs(255 - $colorrgb1['green'] - $colorrgb2['green']);
1133                  $c['blue'] = 255 - abs(255 - $colorrgb1['blue'] - $colorrgb2['blue']);
1134                  break;
1135                  
1136              case IMAGE_TOOLBOX_BLEND_EXCLUTION:    
1137                  $c['red'] = $colorrgb1['red'] + $colorrgb2['red'] - (($colorrgb1['red'] * $colorrgb2['red']) >> 7);
1138                  $c['green'] = $colorrgb1['green'] + $colorrgb2['green'] - (($colorrgb1['green'] * $colorrgb2['green']) >> 7);
1139                  $c['blue'] = $colorrgb1['blue'] + $colorrgb2['blue'] - (($colorrgb1['blue'] * $colorrgb2['blue']) >> 7);
1140                  break;
1141                  
1142              case IMAGE_TOOLBOX_BLEND_OVERLAY:            
1143                  if ($colorrgb1['red'] < 128) {
1144                      $c['red']= ($colorrgb1['red'] * $colorrgb2['red']) >> 7;
1145                  } else {
1146                      $c['red'] = 255 - ((255 - $colorrgb1['red']) * (255 - $colorrgb2['red']) >> 7);
1147                  }
1148                  if ($colorrgb1['green'] < 128) {
1149                      $c['green'] = ($colorrgb1['green'] * $colorrgb2['green']) >> 7;
1150                  } else {
1151                      $c['green'] = 255 - ((255 - $colorrgb1['green']) * (255 - $colorrgb2['green']) >> 7);
1152                  }
1153                  if ($colorrgb1['blue'] < 128) {
1154                      $c['blue'] = ($colorrgb1['blue'] * $colorrgb2['blue']) >> 7;
1155                  } else {
1156                      $c['blue'] = 255 - ((255 - $colorrgb1['blue']) * (255 - $colorrgb2['blue']) >> 7);
1157                  }
1158                  break;
1159                  
1160              default:
1161                  break;
1162          }
1163          return $c;
1164      }
1165      
1166      /**

1167       * convert iso character coding to unicode (PHP conform)

1168       * needed for TTF text generation of special characters (Latin-2)

1169       *

1170       * @access private

1171       */    
1172  	function _iso2uni($isoline) {
1173          $iso2uni = array(
1174              173 => "&#161;",
1175              155 => "&#162;",
1176              156 => "&#163;",
1177              15 => "&#164;",
1178              157 => "&#165;",
1179              124 => "&#166;",
1180              21 => "&#167;",
1181              249 => "&#168;",
1182              184 => "&#169;",
1183              166 => "&#170;",
1184              174 => "&#171;",
1185              170 => "&#172;",
1186              169 => "&#174;",
1187              238 => "&#175;",
1188              248 => "&#176;",
1189              241 => "&#177;",
1190              253 => "&#178;",
1191              252 => "&#179;",
1192              239 => "&#180;",
1193              230 => "&#181;",
1194              20 => "&#182;",
1195              250 => "&#183;",
1196              247 => "&#184;",
1197              251 => "&#185;",
1198              167 => "&#186;",
1199              175 => "&#187;",
1200              172 => "&#188;",
1201              171 => "&#189;",
1202              243 => "&#190;",
1203              168 => "&#191;",
1204              183 => "&#192;",
1205              181 => "&#193;",
1206              182 => "&#194;",
1207              199 => "&#195;",
1208              142 => "&#196;",
1209              143 => "&#197;",
1210              146 => "&#198;",
1211              128 => "&#199;",
1212              212 => "&#200;",
1213              144 => "&#201;",
1214              210 => "&#202;",
1215              211 => "&#203;",
1216              141 => "&#204;",
1217              161 => "&#205;",
1218              140 => "&#206;",
1219              139 => "&#207;",
1220              209 => "&#208;",
1221              165 => "&#209;",
1222              227 => "&#210;",
1223              224 => "&#211;",
1224              226 => "&#212;",
1225              229 => "&#213;",
1226              153 => "&#214;",
1227              158 => "&#215;",
1228              157 => "&#216;",
1229              235 => "&#217;",
1230              233 => "&#218;",
1231              234 => "&#219;",
1232              154 => "&#220;",
1233              237 => "&#221;",
1234              232 => "&#222;",
1235              225 => "&#223;",
1236              133 => "&#224;",
1237              160 => "&#225;",
1238              131 => "&#226;",
1239              198 => "&#227;",
1240              132 => "&#228;",
1241              134 => "&#229;",
1242              145 => "&#230;",
1243              135 => "&#231;",
1244              138 => "&#232;",
1245              130 => "&#233;",
1246              136 => "&#234;",
1247              137 => "&#235;",
1248              141 => "&#236;",
1249              161 => "&#237;",
1250              140 => "&#238;",
1251              139 => "&#239;",
1252              208 => "&#240;",
1253              164 => "&#241;",
1254              149 => "&#242;",
1255              162 => "&#243;",
1256              147 => "&#244;",
1257              228 => "&#245;",
1258              148 => "&#246;",
1259              246 => "&#247;",
1260              155 => "&#248;",
1261              151 => "&#249;",
1262              163 => "&#250;",
1263              150 => "&#251;",
1264              129 => "&#252;",
1265              236 => "&#253;",
1266              231 => "&#254;",
1267              152 => "&#255;"
1268          );
1269          for ($i=0; $i < strlen($isoline); $i++){
1270              $thischar = substr($isoline, $i, 1);
1271              $new = $iso2uni[ord($thischar)];
1272              $uniline .= ($new != "") ? $new : $thischar;
1273          }
1274          return $uniline;
1275      }
1276  
1277      /**

1278       * Writes text over the image

1279       *

1280       * only TTF fonts are supported at the moment

1281       *

1282       * $x:<br>

1283       * You can also use the following keywords ('left', 'center' or 'middle', 'right').<br>

1284       * Additionally you can specify an offset in pixel with the keywords like this 'left +10'.<br>

1285       * (default = 0)

1286       *

1287       * $y:<br>

1288       * You can also use the following keywords ('top', 'center' or 'middle', 'bottom').<br>

1289       * Additionally you can specify an offset in pixel with the keywords like this 'bottom -10'.<br>

1290       * (default = 0)

1291       *

1292       * @param string $text text to be generated.

1293       * @param string $font TTF fontfile to be used. (relative paths are ok).

1294       * @param integer $size textsize.

1295       * @param string $color textcolor in hexformat (e.g. '#FF0000').

1296       * @param string|integer $x horizontal postion in pixel.

1297       * @param string|integer $y vertical postion in pixel.

1298       * @param integer $angle rotation of the text.

1299       */    
1300  	function addText($text, $font, $size, $color, $x, $y, $angle = 0) {
1301          global $HTTP_SERVER_VARS;
1302          
1303          if (substr($font, 0, 1) == DIRECTORY_SEPARATOR || (substr($font, 1, 1) == ":" && (substr($font, 2, 1) == "\\" || substr($font, 2, 1) == "/"))) {
1304              $prepath = '';
1305          } else {
1306              $prepath = substr($HTTP_SERVER_VARS['SCRIPT_FILENAME'], 0, strrpos($HTTP_SERVER_VARS['SCRIPT_FILENAME'], DIRECTORY_SEPARATOR)) . DIRECTORY_SEPARATOR;
1307          }
1308          $text = $this->_iso2uni($text);
1309          if (is_string($x) || is_string($y)) {
1310              $textsize = imagettfbbox($size, $angle, $prepath.$font, $text);
1311              $textwidth = abs($textsize[2]);
1312              $textheight = abs($textsize[7]);
1313              list($xalign, $xalign_offset) = explode(" ", $x);
1314              list($yalign, $yalign_offset) = explode(" ", $y);
1315          }
1316          if (is_string($x)) {
1317              switch ($xalign) {
1318                  case 'left':
1319                      $x = 0 + $xalign_offset;
1320                      break;
1321                      
1322                  case 'right':
1323                      $x = ($this->_img['main']['width'] - $textwidth) + $xalign_offset;
1324                      break;
1325                      
1326                  case 'middle':
1327                  case 'center':
1328                      $x = (($this->_img['main']['width'] - $textwidth) / 2) + $xalign_offset;
1329                      break;
1330              }
1331          }
1332          if (is_string($y)) {
1333              switch ($yalign) {
1334                  case 'top':
1335                      $y = (0 + $textheight) + $yalign_offset;
1336                      break;
1337                      
1338                  case 'bottom':
1339                      $y = ($this->_img['main']['height']) + $yalign_offset;
1340                      break;
1341                      
1342                  case 'middle':
1343                  case 'center':
1344                      $y = ((($this->_img['main']['height'] - $textheight) / 2) + $textheight) + $yalign_offset;
1345                      break;
1346              }
1347          }
1348          imagettftext($this->_img['main']['resource'], $size, $angle, $x, $y, $this->_hexToPHPColor($color), $prepath . $font, $text);
1349          return true;
1350      }
1351      
1352      /**

1353       * workaround function for bicubic resizing. works well for downsizing only. VERY slow. taken from php.net comments

1354       *

1355       * @access private

1356       */    
1357  	function _imageCopyResampledWorkaround(&$dst_img, &$src_img, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h) {
1358          /*

1359          for ($i = 0; $i < imagecolorstotal($src_img); $i++)

1360          {

1361              $colors = ImageColorsForIndex ($src_img, $i);

1362              ImageColorAllocate ($dst_img, $colors['red'],$colors['green'], $colors['blue']);

1363          }

1364          */
1365          $scaleX = ($src_w - 1) / $dst_w;
1366          $scaleY = ($src_h - 1) / $dst_h;
1367  
1368          $scaleX2 = $scaleX / 2.0;
1369          $scaleY2 = $scaleY / 2.0;
1370  
1371          for ($j = $src_y; $j < $src_y + $dst_h; $j++) {
1372              $sY = $j * $scaleY;
1373              for ($i = $src_x; $i < $src_x + $dst_w; $i++) {
1374                  $sX = $i * $scaleX;
1375  
1376                  $c1 = ImageColorsForIndex($src_img, ImageColorAt($src_img, (int) $sX, (int) $sY + $scaleY2));
1377                  $c2 = ImageColorsForIndex($src_img, ImageColorAt($src_img, (int) $sX, (int) $sY));
1378                  $c3 = ImageColorsForIndex($src_img, ImageColorAt($src_img, (int) $sX + $scaleX2, (int) $sY + $scaleY2));
1379                  $c4 = ImageColorsForIndex($src_img, ImageColorAt($src_img, (int) $sX + $scaleX2, (int) $sY));
1380  
1381                  $red = (integer) (($c1['red'] + $c2['red'] + $c3['red'] + $c4['red']) / 4);
1382                  $green = (integer) (($c1['green'] + $c2['green'] + $c3['green'] + $c4['green']) / 4);
1383                  $blue = (integer) (($c1['blue'] + $c2['blue'] + $c3['blue'] + $c4['blue']) / 4);
1384  
1385                  $color = ImageColorClosest ($dst_img, $red, $green,$blue);
1386                  ImageSetPixel ($dst_img, $dst_x + $i - $src_x, $dst_y + $j - $src_y,$color);
1387              }
1388          }
1389      }
1390  
1391      /**

1392       * alternative workaround function for bicubic resizing. works well for downsizing and upsizing. VERY VERY slow. taken from php.net comments

1393       *

1394       * @access private

1395       */    
1396  	function _imageCopyResampledWorkaround2(&$dst_img, &$src_img, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h) {
1397          ImagePaletteCopy ($dst_img, $src_img);
1398          $rX = $src_w / $dst_w;
1399          $rY = $src_h / $dst_h;
1400          $w = 0;
1401          for ($y = $dst_y; $y < $dst_h; $y++) {
1402              $ow = $w; $w = round(($y + 1) * $rY);
1403              $t = 0;
1404              for ($x = $dst_x; $x < $dst_w; $x++) {
1405                  $r = $g = $b = 0; $a = 0;
1406                  $ot = $t; $t = round(($x + 1) * $rX);
1407                  for ($u = 0; $u < ($w - $ow); $u++) {
1408                      for ($p = 0; $p < ($t - $ot); $p++) {
1409                          $c = ImageColorsForIndex ($src_img, ImageColorAt ($src_img, $ot + $p, $ow + $u));
1410                          $r += $c['red'];
1411                          $g += $c['green'];
1412                          $b += $c['blue'];
1413                          $a++;
1414                      }
1415                  }
1416                  ImageSetPixel ($dst_img, $x, $y, ImageColorClosest ($dst_img, $r / $a, $g / $a, $b / $a)); 
1417              }
1418          }
1419      } 
1420  }

title

Description

title

Description

title

Description

title

title

Body