Pastebin launched a little side project called HostCabi.net, check it out ;-)Don't like ads? PRO users don't see any ads ;-)
Guest

Untitled

By: a guest on Nov 3rd, 2012  |  syntax: PHP  |  size: 49.95 KB  |  hits: 141  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  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: Image_Toolbox.class.php,v 1.9 2003/12/05 19:34:01 pappkamerad Exp $
  29.  
  30. if (!defined('IMAGE_TOOLBOX_DEFAULT_JPEG_QUALITY')) {
  31.         define('IMAGE_TOOLBOX_DEFAULT_JPEG_QUALITY', 75);
  32. }
  33. if (!defined('IMAGE_TOOLBOX_DEFAULT_8BIT_COLORS')) {
  34.         define('IMAGE_TOOLBOX_DEFAULT_8BIT_COLORS', 256);
  35. }
  36. if (!defined('IMAGE_TOOLBOX_BIAS_HORIZONTAL')) {
  37.         define('IMAGE_TOOLBOX_BIAS_HORIZONTAL', 1);
  38. }
  39. if (!defined('IMAGE_TOOLBOX_BIAS_VERTICAL')) {
  40.         define('IMAGE_TOOLBOX_BIAS_VERTICAL', 0);
  41. }
  42. if (!defined('IMAGE_TOOLBOX_BLEND_COPY')) {
  43.         define('IMAGE_TOOLBOX_BLEND_COPY', 1);
  44. }
  45. if (!defined('IMAGE_TOOLBOX_BLEND_MULTIPLY')) {
  46.         define('IMAGE_TOOLBOX_BLEND_MULTIPLY', 2);
  47. }
  48. if (!defined('IMAGE_TOOLBOX_BLEND_SCREEN')) {
  49.         define('IMAGE_TOOLBOX_BLEND_SCREEN', 3);
  50. }
  51. if (!defined('IMAGE_TOOLBOX_BLEND_DIFFERENCE')) {
  52.         define('IMAGE_TOOLBOX_BLEND_DIFFERENCE', 4);
  53. }
  54. if (!defined('IMAGE_TOOLBOX_BLEND_NEGATION')) {
  55.         define('IMAGE_TOOLBOX_BLEND_NEGATION', 5);
  56. }
  57. if (!defined('IMAGE_TOOLBOX_BLEND_EXCLUTION')) {
  58.         define('IMAGE_TOOLBOX_BLEND_EXCLUSION', 6);
  59. }
  60. if (!defined('IMAGE_TOOLBOX_BLEND_OVERLAY')) {
  61.         define('IMAGE_TOOLBOX_BLEND_OVERLAY', 7);
  62. }
  63.  
  64. /**
  65.  * PHP image manipulation class
  66.  *
  67.  * This class provides an easy to use library to the PHP GD-based imagefunctions
  68.  *
  69.  * @author Martin Theimer <pappkamerad@decoded.net>
  70.  * @copyright 2003, Martin Theimer
  71.  * @package Image_Toolbox
  72.  * @link http://sourceforge.net/projects/image-toolbox
  73.  * @version 1.1.0
  74.  */
  75. class Image_Toolbox {
  76.  
  77.     /**
  78.      * The prefix for every error message
  79.      *
  80.      * @access private
  81.      * @var string
  82.      */
  83.         var $_error_prefix = 'Image: ';
  84.        
  85.         /**
  86.      * Defines imagetypes and how they are supported by the server
  87.      *
  88.      * @access private
  89.      * @var array
  90.      */
  91.         var $_types = array (
  92.                 1 => array (
  93.                         'ext' => 'gif',
  94.                         'mime' => 'image/gif',
  95.                         'supported' => 0
  96.                 ),
  97.                 2 => array (
  98.                         'ext' => 'jpg',
  99.                         'mime' => 'image/jpeg',
  100.                         'supported' => 0
  101.                 ),
  102.                 3 => array (
  103.                         'ext' => 'png',
  104.                         'mime' => 'image/png',
  105.                         'supported' => 0
  106.                 )
  107.         );
  108.        
  109.         /**
  110.      * Which PHP image resize function to be used
  111.      * imagecopyresampled only supported with GD >= 2.0
  112.      *
  113.      * @access private
  114.      * @var string
  115.      */
  116.         var $_resize_function = 'imagecopyresampled';
  117.  
  118.         /**
  119.      * Stores all image resource data
  120.      *
  121.      * @access private
  122.      * @var array
  123.      */
  124.         var $_img = array (
  125.                 'main' => array (
  126.                         'resource' => 0,
  127.                         'width' => 0,
  128.                         'height' => 0,
  129.                         'bias' => 0,
  130.                         'aspectratio' => 0,
  131.                         'type' => 0,
  132.                         'output_type' => 0,
  133.                         'indexedcolors' => 0,
  134.                         'color' => -1
  135.                 )
  136.         );
  137.        
  138.         /**
  139.      * Which PHP image create function to be used
  140.      * imagecreatetruecolor only supported with GD >= 2.0
  141.      *
  142.      * @access private
  143.      * @var string
  144.      */
  145.         var $_imagecreatefunction = '';
  146.        
  147.     /**
  148.      * The class constructor.
  149.      *
  150.      * Determines the image features of the server and sets the according values.<br>
  151.      * Additionally you can specify a image to be created/loaded. like {@link addImage() addImage}.
  152.      *
  153.      * If no parameter is given, no image resource will be generated<br>
  154.      * Or:<br>
  155.      * <i>string</i> <b>$file</b> imagefile to load<br>
  156.      * Or:<br>
  157.      * <i>integer</i> <b>$width</b> imagewidth of new image to be created<br>
  158.      * <i>integer</i> <b>$height</b> imageheight of new image to be created<br>
  159.      * <i>string</i> <b>$fillcolor</b> optional fill the new image with this color (hexformat, e.g. '#FF0000')<br>
  160.      */
  161.         function Image_Toolbox() {
  162.                 $args = func_get_args();
  163.                 $argc = func_num_args();
  164.                
  165.                 //get GD information. see what types we can handle
  166.                 $gd_info = function_exists('gd_info') ? gd_info() : $this->_gd_info();
  167.                 preg_match("/\A[\D]*([\d+\.]*)[\D]*\Z/", $gd_info['GD Version'], $matches);
  168.                 list($this->_gd_version_string, $this->_gd_version_number) = $matches;
  169.                 $this->_gd_version = substr($this->_gd_version_number, 0, strpos($this->_gd_version_number, '.'));
  170.                 if ($this->_gd_version >= 2) {
  171.                         $this->_imagecreatefunction = 'imagecreatetruecolor';
  172.                         $this->_resize_function = 'imagecopyresampled';
  173.                 } else {
  174.                         $this->_imagecreatefunction = 'imagecreate';
  175.                         $this->_resize_function = 'imagecopyresized';
  176.                 }
  177.                                                
  178.                 $this->_gd_ttf = $gd_info['FreeType Support'];
  179.                 $this->_gd_ps = $gd_info['T1Lib Support'];
  180.                 if ($gd_info['GIF Read Support']) {
  181.                         $this->_types[1]['supported'] = 1;
  182.                         if ($gd_info['GIF Create Support']) {
  183.                                 $this->_types[1]['supported'] = 2;
  184.                         }
  185.                 }
  186.                 if (isset($gd_info['JPG Support']) || isset($gd_info['JPEG Support'])) {
  187.                         $this->_types[2]['supported'] = 2;
  188.                 }
  189.                 if ($gd_info['PNG Support']) {
  190.                         $this->_types[3]['supported'] = 2;
  191.                 }
  192.                
  193.                 //load or create main image
  194.                 if ($argc == 0) {
  195.                         return true;
  196.                 } else {
  197.                         if ($this->_addImage($argc, $args)) {
  198.                                 foreach ($this->_img['operator'] as $key => $value) {
  199.                                         $this->_img['main'][$key] = $value;
  200.                                 }
  201.                                 $this->_img['main']['output_type'] = $this->_img['main']['type'];
  202.                                 unset($this->_img['operator']);
  203.                                 return true;
  204.                         } else {
  205.                                 trigger_error($this->_error_prefix . 'No appropriate constructor found.', E_USER_ERROR);
  206.                                 return null;
  207.                         }
  208.                 }
  209.         }
  210.  
  211.         /**
  212.      * Returns an assocative array with information about the image features of this server
  213.      *
  214.      * Array values:
  215.      * <ul>
  216.      * <li>'gd_version' -> what GD version is installed on this server (e.g. 2.0)</li>
  217.      * <li>'gif' -> 0 = not supported, 1 = reading is supported, 2 = creating is supported</li>
  218.      * <li>'jpg' -> 0 = not supported, 1 = reading is supported, 2 = creating is supported</li>
  219.      * <li>'png' -> 0 = not supported, 1 = reading is supported, 2 = creating is supported</li>
  220.      * <li>'ttf' -> TTF text creation. true = supported, false = not supported
  221.      * </ul>
  222.      *
  223.      * @return array
  224.      */
  225.         function getServerFeatures() {
  226.                 $features = array();
  227.                 $features['gd_version'] = $this->_gd_version_number;
  228.                 $features['gif'] = $this->_types[1]['supported'];
  229.                 $features['jpg'] = $this->_types[2]['supported'];
  230.                 $features['png'] = $this->_types[3]['supported'];
  231.                 $features['ttf'] = $this->_gd_ttf;
  232.                 return $features;
  233.         }
  234.  
  235.         /**
  236.      * Flush all image resources and init a new one
  237.      *
  238.      * Parameter:<br>
  239.      * <i>string</i> <b>$file</b> imagefile to load<br>
  240.      * Or:<br>
  241.      * <i>integer</i> <b>$width</b> imagewidth of new image to be created<br>
  242.      * <i>integer</i> <b>$height</b> imageheight of new image to be created<br>
  243.      * <i>string</i> <b>$fillcolor</b> optional fill the new image with this color (hexformat, e.g. '#FF0000')<br>
  244.      */
  245.         function newImage() {
  246.                 $args = func_get_args();
  247.                 $argc = func_num_args();
  248.                
  249.                 if ($this->_addImage($argc, $args)) {
  250.                         foreach ($this->_img['operator'] as $key => $value) {
  251.                                 $this->_img['main'][$key] = $value;
  252.                         }
  253.                         $this->_img['main']['output_type'] = $this->_img['main']['type'];
  254.                         unset($this->_img['operator']);
  255.                         return true;
  256.                 } else {
  257.                         trigger_error($this->_error_prefix . 'No appropriate constructor found.', E_USER_ERROR);
  258.                         return null;
  259.                 }
  260.         }
  261.  
  262.         /**
  263.      * Reimplements the original PHP {@link gd_info()} function for older PHP versions
  264.      *
  265.      * @access private
  266.      * @return array associative array with info about the GD library of the server
  267.      */
  268.         function _gd_info() {
  269.                 $array = array(
  270.                 "GD Version" => "",
  271.                         "FreeType Support" => false,
  272.                         "FreeType Linkage" => "",
  273.                         "T1Lib Support" => false,
  274.                         "GIF Read Support" => false,
  275.                         "GIF Create Support" => false,
  276.                         "JPG Support" => false,
  277.                         "PNG Support" => false,
  278.                         "WBMP Support" => false,
  279.                         "XBM Support" => false
  280.                 );
  281.        
  282.                 $gif_support = 0;
  283.                 ob_start();
  284.                 eval("phpinfo();");
  285.                 $info = ob_get_contents();
  286.                 ob_end_clean();
  287.      
  288.                 foreach(explode("\n", $info) as $line) {
  289.                         if(strpos($line, "GD Version") !== false)
  290.                                 $array["GD Version"] = trim(str_replace("GD Version", "", strip_tags($line)));
  291.                         if(strpos($line, "FreeType Support") !== false)
  292.                                 $array["FreeType Support"] = trim(str_replace("FreeType Support", "", strip_tags($line)));
  293.                         if(strpos($line, "FreeType Linkage") !== false)
  294.                                 $array["FreeType Linkage"] = trim(str_replace("FreeType Linkage", "", strip_tags($line)));
  295.                         if(strpos($line, "T1Lib Support") !== false)
  296.                                 $array["T1Lib Support"] = trim(str_replace("T1Lib Support", "", strip_tags($line)));
  297.                         if(strpos($line, "GIF Read Support") !== false)
  298.                                 $array["GIF Read Support"] = trim(str_replace("GIF Read Support", "", strip_tags($line)));
  299.                         if(strpos($line, "GIF Create Support") !== false)
  300.                                 $array["GIF Create Support"] = trim(str_replace("GIF Create Support", "", strip_tags($line)));
  301.                         if(strpos($line, "GIF Support") !== false)
  302.                                 $gif_support = trim(str_replace("GIF Support", "", strip_tags($line)));
  303.                         if(strpos($line, "JPG Support") !== false)
  304.                                 $array["JPG Support"] = trim(str_replace("JPG Support", "", strip_tags($line)));
  305.                         if(strpos($line, "PNG Support") !== false)
  306.                                 $array["PNG Support"] = trim(str_replace("PNG Support", "", strip_tags($line)));
  307.                         if(strpos($line, "WBMP Support") !== false)
  308.                                 $array["WBMP Support"] = trim(str_replace("WBMP Support", "", strip_tags($line)));
  309.                         if(strpos($line, "XBM Support") !== false)
  310.                                 $array["XBM Support"] = trim(str_replace("XBM Support", "", strip_tags($line)));
  311.                 }
  312.        
  313.                 if($gif_support === "enabled") {
  314.                         $array["GIF Read Support"] = true;
  315.                         $array["GIF Create Support"] = true;
  316.                 }
  317.  
  318.                 if($array["FreeType Support"] === "enabled") {
  319.                         $array["FreeType Support"] = true;
  320.                 }
  321.  
  322.         if($array["T1Lib Support"] === "enabled") {
  323.             $array["T1Lib Support"] = true;
  324.         }
  325.        
  326.                 if($array["GIF Read Support"] === "enabled") {
  327.                         $array["GIF Read Support"] = true;
  328.                 }
  329.  
  330.                 if($array["GIF Create Support"] === "enabled") {
  331.                         $array["GIF Create Support"] = true;
  332.                 }
  333.  
  334.                 if($array["JPG Support"] === "enabled") {
  335.                         $array["JPG Support"] = true;
  336.                 }
  337.            
  338.                 if($array["PNG Support"] === "enabled") {
  339.                         $array["PNG Support"] = true;
  340.                 }
  341.            
  342.                 if($array["WBMP Support"] === "enabled") {
  343.                         $array["WBMP Support"] = true;
  344.                 }
  345.            
  346.                 if($array["XBM Support"] === "enabled") {
  347.                         $array["XBM Support"] = true;
  348.                 }
  349.  
  350.                 return $array;
  351.     }
  352.  
  353.         /**
  354.      * Convert a color defined in hexvalues to the PHP color format
  355.      *
  356.      * @access private
  357.      * @param string $hex color value in hexformat (e.g. '#FF0000')
  358.      * @return integer color value in PHP format
  359.      */
  360.         function _hexToPHPColor($hex) {
  361.                 $length = strlen($hex);
  362.                 $dr = hexdec(substr($hex, $length - 6, 2));
  363.                 $dg = hexdec(substr($hex, $length - 4, 2));
  364.                 $db = hexdec(substr($hex, $length - 2, 2));
  365.                 $color = ($dr << 16) + ($dg << 8) + $db;
  366.                 return $color;
  367.         }
  368.        
  369.         /**
  370.      * Convert a color defined in hexvalues to corresponding dezimal values
  371.      *
  372.      * @access private
  373.      * @param string $hex color value in hexformat (e.g. '#FF0000')
  374.      * @return array associative array with color values in dezimal format (fields: 'red', 'green', 'blue')
  375.      */
  376.         function _hexToDecColor($hex) {
  377.                 $length = strlen($hex);
  378.                 $color['red'] = hexdec(substr($hex, $length - 6, 2));
  379.                 $color['green'] = hexdec(substr($hex, $length - 4, 2));
  380.                 $color['blue'] = hexdec(substr($hex, $length - 2, 2));
  381.                 return $color;
  382.         }
  383.  
  384.         /**
  385.      * Generate a new image resource based on the given parameters
  386.      *
  387.      * Parameter:
  388.      * <i>string</i> <b>$file</b> imagefile to load<br>
  389.      * Or:<br>
  390.      * <i>integer</i> <b>$width</b> imagewidth of new image to be created<br>
  391.      * <i>integer</i> <b>$height</b> imageheight of new image to be created<br>
  392.      * <i>string</i> <b>$fillcolor</b> optional fill the new image with this color (hexformat, e.g. '#FF0000')<br>
  393.      *
  394.      * @access private
  395.      */
  396.         function _addImage($argc, $args) {
  397.                 if (($argc == 2 || $argc == 3) && is_int($args[0]) && is_int($args[1]) && (is_string($args[2]) || !isset($args[2]))) {
  398.                         //neues leeres bild mit width und height (fillcolor optional)
  399.                         $this->_img['operator']['width'] = $args[0];
  400.             $this->_img['operator']['height'] = $args[1];
  401.             ($this->_img['operator']['width'] >= $this->_img['operator']['height']) ? ($this->_img['operator']['bias'] = IMAGE_TOOLBOX_BIAS_HORIZONTAL) : ($this->_img['operator']['bias'] = IMAGE_TOOLBOX_BIAS_VERTICAL);
  402.             $this->_img['operator']['aspectratio'] = $this->_img['operator']['width'] / $this->_img['operator']['height'];
  403.             $this->_img['operator']['indexedcolors'] = 0;
  404.             $functionname = $this->_imagecreatefunction;
  405.             $this->_img['operator']['resource'] = $functionname($this->_img['operator']['width'], $this->_img['operator']['height']);
  406.             // set default type jpg.
  407.             $this->_img['operator']['type'] = 2;
  408.             if (isset($args[2]) && is_string($args[2])) {
  409.                 //neues bild mit farbe fllen
  410.                 $fillcolor = $this->_hexToPHPColor($args[2]);
  411.                 imagefill($this->_img['operator']['resource'], 0, 0, $fillcolor);
  412.                 $this->_img['operator']['color'] = $fillcolor;
  413.             } else {
  414.                 $this->_img['operator']['color'] = 0;
  415.                         }
  416.                 } elseif ($argc == 1 && is_string($args[0])) {
  417.                         //bild aus datei laden. width und height original gr”sse
  418.                         $this->_img['operator'] = $this->_loadFile($args[0]);
  419.                         $this->_img['operator']['indexedcolors'] = imagecolorstotal($this->_img['operator']['resource']);
  420.                         $this->_img['operator']['color'] = -1;
  421.                 } else {
  422.                         return false;
  423.                 }
  424.                 return true;
  425.         }
  426.  
  427.         /**
  428.      * Loads a image file
  429.      *
  430.      * @access private
  431.      * @param string $filename imagefile to load
  432.      * @return array associative array with the loaded filedata
  433.      */
  434.         function _loadFile($filename) {
  435.                 if (file_exists($filename)) {
  436.                         $info = getimagesize($filename);
  437.                         $filedata['width'] = $info[0];
  438.                         $filedata['height'] = $info[1];
  439.                         ($filedata['width'] >= $filedata['height']) ? ($filedata['bias'] = IMAGE_TOOLBOX_BIAS_HORIZONTAL) : ($filedata['bias'] = IMAGE_TOOLBOX_BIAS_VERTICAL);
  440.                 $filedata['aspectratio'] = $filedata['width'] / $filedata['height'];
  441.                         $filedata['type'] = $info[2];
  442.  
  443.                         if ($this->_types[$filedata['type']]['supported'] < 1) {
  444.                                 trigger_error($this->_error_prefix . 'Imagetype ('.$this->_types[$filedata['type']]['ext'].') not supported for reading.', E_USER_ERROR);
  445.                                 return null;
  446.                         }
  447.                         switch ($filedata['type']) {
  448.                                 case 1:
  449.                                         $dummy = imagecreatefromgif($filename);
  450.                                         $functionname = $this->_imagecreatefunction;
  451.                                         $filedata['resource'] = $functionname($filedata['width'], $filedata['height']);
  452.                                         imagecopy($filedata['resource'], $dummy, 0, 0, 0, 0, $filedata['width'], $filedata['height']);
  453.                                         imagedestroy($dummy);
  454.                                         break;
  455.                                        
  456.                                 case 2:
  457.                                         $filedata['resource'] = imagecreatefromjpeg($filename);
  458.                                         break;
  459.                                        
  460.                                 case 3:
  461.                                         $dummy = imagecreatefrompng($filename);
  462.                                         if (imagecolorstotal($dummy) != 0) {
  463.                                                 $functionname = $this->_imagecreatefunction;
  464.                                                 $filedata['resource'] = $functionname($filedata['width'], $filedata['height']);
  465.                                                 imagecopy($filedata['resource'], $dummy, 0, 0, 0, 0, $filedata['width'], $filedata['height']);
  466.                                         } else {
  467.                                                 $filedata['resource'] = $dummy;
  468.                                         }
  469.                                         unset($dummy);
  470.                                         break;
  471.                                        
  472.                                 default:
  473.                                         trigger_error($this->_error_prefix . 'Imagetype not supported.', E_USER_ERROR);
  474.                                         return null;
  475.                         }
  476.                         return $filedata;
  477.                 } else {
  478.                         trigger_error($this->_error_prefix . 'Imagefile (' . $filename . ') does not exist.', E_USER_ERROR);
  479.                         return null;
  480.                 }
  481.         }
  482.        
  483.         /**
  484.      * Output a image to the browser
  485.      *
  486.      * $output_type can be one of the following:<br>
  487.      * <ul>
  488.      * <li>'gif' -> gif image (if supported) (8-bit indexed colors)</li>
  489.      * <li>'png' -> png image (if supported) (truecolor)</li>
  490.      * <li>'png8' -> png image (if supported) (8-bit indexed colors)</li>
  491.      * <li>'jpg' -> jpeg image (if supported) (truecolor)</li>
  492.      * </ul>
  493.      * (default: same as original)
  494.      *
  495.      * $dither:<br>
  496.      * If this is true than dither is used on the conversion from truecolor to 8-bit indexed imageformats (png8, gif)<br>
  497.      * (default = false)
  498.      *
  499.      * @param string|integer $output_type type of outputted image
  500.      * @param integer $output_quality jpeg quality of outputted image (default: IMAGE_TOOLBOX_DEFAULT_JPEG_QUALITY)
  501.      * @param bool $dither use dither
  502.      * @return bool true on success, otherwise false
  503.      */
  504.         function output($output_type = false, $output_quality = false, $dither = false) {
  505.                 if ($output_type === false) {
  506.                         $output_type = $this->_img['main']['output_type'];
  507.                 }
  508.                 switch ($output_type) {
  509.                         case 1:
  510.                         case 'gif':
  511.                         case 'GIF':
  512.                                 if ($this->_types[1]['supported'] < 2) {
  513.                                         trigger_error($this->_error_prefix . 'Imagetype ('.$this->_types[$output_type]['ext'].') not supported for creating/writing.', E_USER_ERROR);
  514.                                         return null;
  515.                                 }
  516.                                 header ('Content-type: ' . $this->_types[$output_type]['mime']);
  517.                                 if ($this->_gd_version >= 2) {
  518.                                         if ($this->_img['main']['indexedcolors'] == 0) {
  519.                                                 $dummy = imagecreatetruecolor($this->_img['main']['width'], $this->_img['main']['height']);
  520.                                                 imagecopy($dummy, $this->_img['main']['resource'], 0, 0, 0, 0, $this->_img['main']['width'], $this->_img['main']['height']);
  521.                                                 if ($output_quality === false) {
  522.                                                         $output_quality = IMAGE_TOOLBOX_DEFAULT_8BIT_COLORS;
  523.                                                 }
  524.                                                 imagetruecolortopalette($dummy, $dither, $output_quality);
  525.                                         }
  526.                                         imagegif($dummy);
  527.                                         imagedestroy($dummy);
  528.                                 }
  529.                                 else {
  530.                                         imagegif($this->_img['main']['resource']);
  531.                                 }
  532.                                 break;
  533.                        
  534.                         case 2:
  535.                         case '2':
  536.                         case 'jpg':
  537.                         case 'jpeg':
  538.                         case 'JPG':
  539.                         case 'JPEG':
  540.                                 if ($this->_types[2]['supported'] < 2) {
  541.                                         trigger_error($this->_error_prefix . 'Imagetype ('.$this->_types[$output_type]['ext'].') not supported for creating/writing.', E_USER_ERROR);
  542.                                         return null;
  543.                                 }
  544.                                 header ('Content-type: ' . $this->_types[$output_type]['mime']);
  545.                                 if ($output_quality === false) {
  546.                                         $output_quality = IMAGE_TOOLBOX_DEFAULT_JPEG_QUALITY;
  547.                                 }
  548.                                 imagejpeg($this->_img['main']['resource'], '', $output_quality);
  549.                                 break;
  550.                                
  551.                         case 3:
  552.                         case '3':
  553.                         case 'png':
  554.                         case 'PNG':
  555.                         case 'png24':
  556.                         case 'PNG24':
  557.                                 if ($this->_types[3]['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.                                 imagepng($this->_img['main']['resource']);
  563.                                 break;
  564.                                
  565.                         case 4:
  566.                         case '4':
  567.                         case 'png8':
  568.                         case 'PNG8':
  569.                                 if ($this->_types[3]['supported'] < 2) {
  570.                                         trigger_error($this->_error_prefix . 'Imagetype ('.$this->_types[$output_type]['ext'].') not supported for creating/writing.', E_USER_ERROR);
  571.                                         return null;
  572.                                 }
  573.                                 header ('Content-type: ' . $this->_types[$output_type]['mime']);
  574.                                 if ($this->_gd_version >= 2) {
  575.                                         if ($this->_img['main']['indexedcolors'] == 0) {
  576.                                                 $dummy = imagecreatetruecolor($this->_img['main']['width'], $this->_img['main']['height']);
  577.                                                 imagecopy($dummy, $this->_img['main']['resource'], 0, 0, 0, 0, $this->_img['main']['width'], $this->_img['main']['height']);
  578.                                                 if ($output_quality === false) {
  579.                                                         $output_quality = IMAGE_TOOLBOX_DEFAULT_8BIT_COLORS;
  580.                                                 }
  581.                                                 imagetruecolortopalette($dummy, $dither, $output_quality);
  582.                                         }
  583.                                         imagepng($dummy);
  584.                                         imagedestroy($dummy);
  585.                                 }
  586.                                 else {
  587.                                         imagepng($this->_img['main']['resource']);
  588.                                 }
  589.                                 break;
  590.                                
  591.                         default:
  592.                                 trigger_error($this->_error_prefix . 'Output-Imagetype not supported.', E_USER_ERROR);
  593.                                 return null;
  594.                 }
  595.                 return true;
  596.         }
  597.        
  598.         /**
  599.      * Save a image to disk
  600.      *
  601.      * $output_type can be one of the following:<br>
  602.      * <ul>
  603.      * <li>'gif' -> gif image (if supported) (8-bit indexed colors)</li>
  604.      * <li>'png' -> png image (if supported) (truecolor)</li>
  605.      * <li>'png8' -> png image (if supported) (8-bit indexed colors)</li>
  606.      * <li>'jpg' -> jpeg image (if supported) (truecolor)</li>
  607.      * </ul>
  608.      * (default: same as original)
  609.      *
  610.      * $dither:<br>
  611.      * If this is true than dither is used on the conversion from truecolor to 8-bit indexed imageformats (png8, gif)<br>
  612.      * (default = false)
  613.      *
  614.      * @param string $filename filename of saved image
  615.      * @param string|integer $output_type type of saved image
  616.      * @param integer $output_quality jpeg quality of saved image (default: IMAGE_TOOLBOX_DEFAULT_JPEG_QUALITY)
  617.      * @param bool $dither use dither
  618.      * @return bool true on success, otherwise false
  619.      */
  620.         function save($filename, $output_type = false, $output_quality = false, $dither = false) {
  621.                 if ($output_type === false) {
  622.                         $output_type = $this->_img['main']['output_type'];
  623.                 }
  624.                 switch ($output_type) {
  625.                         case 1:
  626.                         case 'gif':
  627.                         case 'GIF':
  628.                                 if ($this->_types[1]['supported'] < 2) {
  629.                                         trigger_error($this->_error_prefix . 'Imagetype ('.$this->_types[$output_type]['ext'].') not supported for creating/writing.', E_USER_ERROR);
  630.                                         return null;
  631.                                 }
  632.                                 if ($this->_gd_version >= 2) {
  633.                                         if ($this->_img['main']['indexedcolors'] == 0) {
  634.                                                 $dummy = imagecreatetruecolor($this->_img['main']['width'], $this->_img['main']['height']);
  635.                                                 imagecopy($dummy, $this->_img['main']['resource'], 0, 0, 0, 0, $this->_img['main']['width'], $this->_img['main']['height']);
  636.                                                 if ($output_quality === false) {
  637.                                                         $output_quality = IMAGE_TOOLBOX_DEFAULT_8BIT_COLORS;
  638.                                                 }
  639.                                                 imagetruecolortopalette($dummy, $dither, $output_quality);
  640.                                         }
  641.                                         imagegif($dummy, $filename);
  642.                                         imagedestroy($dummy);
  643.                                 }
  644.                                 else {
  645.                                         imagegif($this->_img['main']['resource']);
  646.                                 }
  647.                                 break;
  648.                        
  649.                         case 2:
  650.                         case '2':
  651.                         case 'jpg':
  652.                         case 'jpeg':
  653.                         case 'JPG':
  654.                         case 'JPEG':
  655.                                 if ($this->_types[2]['supported'] < 2) {
  656.                                         trigger_error($this->_error_prefix . 'Imagetype ('.$this->_types[$output_type]['ext'].') not supported for creating/writing.', E_USER_ERROR);
  657.                                         return null;
  658.                                 }
  659.                                 if ($output_quality === false) {
  660.                                         $output_quality = IMAGE_TOOLBOX_DEFAULT_JPEG_QUALITY;
  661.                                 }
  662.                                 imagejpeg($this->_img['main']['resource'], $filename, $output_quality);
  663.                                 break;
  664.                                
  665.                         case 3:
  666.                         case '3':
  667.                         case 'png':
  668.                         case 'PNG':
  669.                         case 'png24':
  670.                         case 'PNG24':
  671.                                 if ($this->_types[3]['supported'] < 2) {
  672.                                         trigger_error($this->_error_prefix . 'Imagetype ('.$this->_types[$output_type]['ext'].') not supported for creating/writing.', E_USER_ERROR);
  673.                                         return null;
  674.                                 }
  675.                                 header ('Content-type: ' . $this->_types[$output_type]['mime']);
  676.                                 imagepng($this->_img['main']['resource'], $filename);
  677.                                 break;
  678.                                
  679.                         case 4:
  680.                         case '4':
  681.                         case 'png8':
  682.                         case 'PNG8':
  683.                                 if ($this->_types[3]['supported'] < 2) {
  684.                                         trigger_error($this->_error_prefix . 'Imagetype ('.$this->_types[$output_type]['ext'].') not supported for creating/writing.', E_USER_ERROR);
  685.                                         return null;
  686.                                 }
  687.                                 if ($this->_gd_version >= 2) {
  688.                                         if ($this->_img['main']['indexedcolors'] == 0) {
  689.                                                 $dummy = imagecreatetruecolor($this->_img['main']['width'], $this->_img['main']['height']);
  690.                                                 imagecopy($dummy, $this->_img['main']['resource'], 0, 0, 0, 0, $this->_img['main']['width'], $this->_img['main']['height']);
  691.                                                 if ($output_quality === false) {
  692.                                                         $output_quality = IMAGE_TOOLBOX_DEFAULT_8BIT_COLORS;
  693.                                                 }
  694.                                                 imagetruecolortopalette($dummy, $dither, $output_quality);
  695.                                         }
  696.                                         imagepng($dummy, $filename);
  697.                                         imagedestroy($dummy);
  698.                                 }
  699.                                 else {
  700.                                         imagepng($this->_img['main']['resource'], $filename);
  701.                                 }
  702.                                 break;
  703.                                
  704.                         default:
  705.                                 trigger_error($this->_error_prefix . 'Output-Imagetype not supported.', E_USER_ERROR);
  706.                                 return null;
  707.                 }
  708.                 return true;
  709.         }
  710.        
  711.         /**
  712.      * Sets the resize method of choice
  713.      *
  714.      * $method can be one of the following:<br>
  715.      * <ul>
  716.      * <li>'resize' -> supported by every version of GD (fast but ugly resize of image)</li>
  717.      * <li>'resample' -> only supported by GD version >= 2.0 (slower but antialiased resize of image)</li>
  718.      * <li>'workaround' -> supported by every version of GD (workaround function for bicubic resizing, downsizing, VERY slow!, taken from php.net comments)</li>
  719.      * <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>
  720.      * </ul>
  721.      *
  722.      * @param string|integer $method resize method
  723.      * @return bool true on success, otherwise false
  724.      */
  725.         function setResizeMethod($method) {
  726.                 switch ($method) {
  727.                         case 1:
  728.                         case '1':
  729.                         case 'resize':
  730.                                 $this->_resize_function = 'imagecopyresized';
  731.                                 break;
  732.                                
  733.                         case 2:
  734.                         case '2':
  735.                         case 'resample':
  736.                                 if (!function_exists('imagecopyresampled')) {
  737.                                         // no error message. just return false.
  738.                                         return null;
  739.                                 }
  740.                                 $this->_resize_function = 'imagecopyresampled';
  741.                                 break;
  742.                                
  743.                         case 3:
  744.                         case '3':
  745.                         case 'resample_workaround':
  746.                         case 'workaround':
  747.                         case 'bicubic':
  748.                                 $this->_resize_function = '$this->_imageCopyResampledWorkaround';
  749.                                 break;
  750.                                
  751.                         case 4:
  752.                         case '4':
  753.                         case 'resample_workaround2':
  754.                         case 'workaround2':
  755.                         case 'bicubic2':
  756.                                 $this->_resize_function = '$this->_imageCopyResampledWorkaround2';
  757.                                 break;
  758.                                
  759.                         default:
  760.                                 trigger_error($this->_error_prefix . 'Resizemethod not supported.', E_USER_ERROR);
  761.                                 return null;
  762.                 }
  763.                 return true;
  764.         }
  765.        
  766.         /**
  767.      * Resize the current image
  768.      *
  769.      * if $width = 0 the new width will be calculated from the $height value preserving the correct aspectratio.<br>
  770.      *
  771.      * if $height = 0 the new height will be calculated from the $width value preserving the correct aspectratio.<br>
  772.      *
  773.      * $mode can be one of the following:<br>
  774.      * <ul>
  775.      * <li>0 -> image will be resized to the new output size, regardless of the original aspectratio. (default)</li>
  776.      * <li>1 -> image will be cropped if necessary to preserve the aspectratio and avoid image distortions.</li>
  777.      * <li>2 -> image will be resized preserving its original aspectratio. differences to the new outputsize will be filled with $bgcolor</li>
  778.      * </ul>
  779.      *
  780.      * 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>
  781.      * 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>
  782.      * (default = false)
  783.      *
  784.      * @param integer $width new width of image
  785.      * @param integer $height new height of image
  786.      * @param integer $mode resize mode
  787.      * @param bool $autorotate use autorotating
  788.      * @param string $bgcolor background fillcolor (hexformat, e.g. '#FF0000')
  789.      * @return bool true on success, otherwise false
  790.      */
  791.         function newOutputSize($width, $height, $mode = 0, $autorotate = false, $bgcolor = '#000000') {
  792.                 if ($width > 0 && $height > 0 && is_int($width) && is_int($height)) {
  793.                         //ignore aspectratio
  794.                         if (!$mode) {
  795.                                 //do not crop to get correct aspectratio
  796.                                 ($width >= $height) ? ($this->_img['target']['bias'] = IMAGE_TOOLBOX_BIAS_HORIZONTAL) : ($this->_img['target']['bias'] = IMAGE_TOOLBOX_BIAS_VERTICAL);
  797.                                 if ($this->_img['main']['bias'] == $this->_img['target']['bias'] || !$autorotate) {
  798.                                         $this->_img['target']['width'] = $width;
  799.                                         $this->_img['target']['height'] = $height;
  800.                                 } else {
  801.                                         $this->_img['target']['width'] = $height;
  802.                                         $this->_img['target']['height'] = $width;
  803.                                 }
  804.                                 $this->_img['target']['aspectratio'] = $this->_img['target']['width'] / $this->_img['target']['height'];
  805.                                
  806.                                 $cpy_w = $this->_img['main']['width'];
  807.                                 $cpy_h = $this->_img['main']['height'];
  808.                                 $cpy_w_offset = 0;
  809.                                 $cpy_h_offset = 0;
  810.                         } elseif ($mode == 1) {
  811.                                 //crop to get correct aspectratio
  812.                                 ($width >= $height) ? ($this->_img['target']['bias'] = IMAGE_TOOLBOX_BIAS_HORIZONTAL) : ($this->_img['target']['bias'] = IMAGE_TOOLBOX_BIAS_VERTICAL);
  813.                                 if ($this->_img['main']['bias'] == $this->_img['target']['bias'] || !$autorotate) {
  814.                                         $this->_img['target']['width'] = $width;
  815.                                         $this->_img['target']['height'] = $height;
  816.                                 } else {
  817.                                         $this->_img['target']['width'] = $height;
  818.                                         $this->_img['target']['height'] = $width;
  819.                                 }
  820.                                 $this->_img['target']['aspectratio'] = $this->_img['target']['width'] / $this->_img['target']['height'];
  821.                                
  822.                                 if ($this->_img['main']['width'] / $this->_img['target']['width'] >= $this->_img['main']['height'] / $this->_img['target']['height']) {
  823.                                         $cpy_h = $this->_img['main']['height'];
  824.                                         $cpy_w = (integer) $this->_img['main']['height'] * $this->_img['target']['aspectratio'];
  825.                                         $cpy_w_offset = (integer) ($this->_img['main']['width'] - $cpy_w) / 2;
  826.                                         $cpy_h_offset = 0;
  827.                                 } else {
  828.                                         $cpy_w = $this->_img['main']['width'];
  829.                                         $cpy_h = (integer) $this->_img['main']['width'] / $this->_img['target']['aspectratio'];
  830.                                         $cpy_h_offset = (integer) ($this->_img['main']['height'] - $cpy_h) / 2;
  831.                                         $cpy_w_offset = 0;
  832.                                 }
  833.                         }
  834.                         elseif ($mode == 2) {
  835.                                 //fill remaining background with a color to keep aspectratio
  836.                                 $final_aspectratio = $width / $height;
  837.                                 if ($final_aspectratio < $this->_img['main']['aspectratio']) {
  838.                                         $this->_img['target']['width'] = $width;
  839.                                         $this->_img['target']['height'] = (integer) $width / $this->_img['main']['aspectratio'];
  840.                                         $cpy_w_offset2 = 0;
  841.                                         $cpy_h_offset2 = (integer) (($height - $this->_img['target']['height']) / 2);
  842.                                 }
  843.                                 else {
  844.                                         $this->_img['target']['height'] = $height;
  845.                                         $this->_img['target']['width'] = (integer) $height * $this->_img['main']['aspectratio'];
  846.                                         $cpy_h_offset2 = 0;
  847.                                         $cpy_w_offset2 = (integer) (($width - $this->_img['target']['width']) / 2);
  848.                                 }
  849.                                 $this->_img['target']['aspectratio'] = $this->_img['main']['aspectratio'];
  850.                                 $cpy_w = $this->_img['main']['width'];
  851.                                 $cpy_h = $this->_img['main']['height'];
  852.                                 $cpy_w_offset = 0;
  853.                                 $cpy_h_offset = 0;
  854.                         }
  855.                 } elseif (($width == 0 && $height > 0) || ($width > 0 && $height == 0) && is_int($width) && is_int($height)) {
  856.                         //keep aspectratio
  857.                         if ($autorotate == true) {
  858.                                 if ($this->_img['main']['bias'] == IMAGE_TOOLBOX_BIAS_HORIZONTAL && $width > 0) {
  859.                                         $height = $width;
  860.                                         $width = 0;
  861.                                 } elseif ($this->_img['main']['bias'] == IMAGE_TOOLBOX_BIAS_VERTICAL && $height > 0) {
  862.                                         $width = $height;
  863.                                         $height = 0;
  864.                                 }
  865.                         }
  866.                         ($width >= $height) ? ($this->_img['target']['bias'] = IMAGE_TOOLBOX_BIAS_HORIZONTAL) : ($this->_img['target']['bias'] = IMAGE_TOOLBOX_BIAS_VERTICAL);
  867.                         if ($width != 0) {
  868.                                 $this->_img['target']['width'] = $width;
  869.                                 $this->_img['target']['height'] = (integer) $width / $this->_img['main']['aspectratio'];
  870.                         } else {
  871.                                 $this->_img['target']['height'] = $height;
  872.                                 $this->_img['target']['width'] = (integer) $height * $this->_img['main']['aspectratio'];
  873.                         }
  874.                         $this->_img['target']['aspectratio'] = $this->_img['main']['aspectratio'];
  875.                        
  876.                         $cpy_w = $this->_img['main']['width'];
  877.                         $cpy_h = $this->_img['main']['height'];
  878.                         $cpy_w_offset = 0;
  879.                         $cpy_h_offset = 0;
  880.                 } else {
  881.                         trigger_error($this->_error_prefix . 'Outputwidth and -height must be integers greater zero.', E_USER_ERROR);
  882.                         return null;
  883.                 }
  884.                
  885.                 //create resized picture
  886.                 $functionname = $this->_imagecreatefunction;
  887.                 $dummy = $functionname($this->_img['target']['width'] + 1, $this->_img['target']['height'] + 1);
  888.                 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);');
  889.                 if ($mode == 2) {
  890.                         $this->_img['target']['resource'] = $functionname($width, $height);
  891.                         $fillcolor = $this->_hexToPHPColor($bgcolor);
  892.             imagefill($this->_img['target']['resource'], 0, 0, $fillcolor);
  893.                 } else {
  894.                         $this->_img['target']['resource'] = $functionname($this->_img['target']['width'], $this->_img['target']['height']);
  895.                         $cpy_w_offset2 = 0;
  896.                         $cpy_h_offset2 = 0;
  897.                 }
  898.                 imagecopy($this->_img['target']['resource'], $dummy, $cpy_w_offset2, $cpy_h_offset2, 0, 0, $this->_img['target']['width'], $this->_img['target']['height']);
  899.                 imagedestroy($dummy);
  900.                
  901.                 if ($mode == 2) {
  902.                         $this->_img['target']['width'] = $width;
  903.             $this->_img['target']['height'] = $height;
  904.         }
  905.                 //update _img['main'] with new data
  906.                 foreach ($this->_img['target'] as $key => $value) {
  907.                         $this->_img['main'][$key] = $value;
  908.                 }
  909.                 unset ($this->_img['target']);
  910.                
  911.                 return true;
  912.         }
  913.  
  914.         /**
  915.      * Adds a new image resource based on the given parameters.
  916.      *
  917.      * It does not overwrite the existing image resource.<br>
  918.      * Instead it is used to load a second image to merge with the existing image.
  919.      *
  920.      * Parameter:<br>
  921.      * <i>string</i> <b>$file</b> imagefile to load<br>
  922.      * Or:<br>
  923.      * <i>integer</i> <b>$width</b> imagewidth of new image to be created<br>
  924.      * <i>integer</i> <b>$height</b> imageheight of new image to be created<br>
  925.      * <i>string</i> <b>$fillcolor</b> optional fill the new image with this color (hexformat, e.g. '#FF0000')<br>
  926.      */
  927.         function addImage() {
  928.                 $args = func_get_args();
  929.                 $argc = func_num_args();
  930.                
  931.                 if ($this->_addImage($argc, $args)) {
  932.                         return true;
  933.                 } else {
  934.                         trigger_error($this->_error_prefix . 'failed to add image.', E_USER_ERROR);
  935.                         return false;
  936.                 }
  937.         }
  938.        
  939.         /**
  940.      * Blend two images.
  941.      *
  942.      * Original image and the image loaded with {@link addImage() addImage}<br>
  943.      * NOTE: This operation can take very long and is not intended for realtime use.
  944.      * (but of course depends on the power of your server :) )
  945.      *
  946.      * 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>
  947.      *
  948.      * $x:<br>
  949.      * negative values are possible.<br>
  950.      * You can also use the following keywords ('left', 'center' or 'middle', 'right').<br>
  951.      * Additionally you can specify an offset in pixel with the keywords like this 'left +10'.<br>
  952.      * (default = 0)
  953.      *
  954.      * $y:<br>
  955.      * negative values are possible.<br>
  956.      * You can also use the following keywords ('top', 'center' or 'middle', 'bottom').<br>
  957.      * Additionally you can specify an offset in pixel with the keywords like this 'bottom -10'.<br>
  958.      * (default = 0)
  959.      *
  960.      * Possible values for $mode:
  961.      * <ul>
  962.      *  <li>IMAGE_TOOLBOX_BLEND_COPY</li>
  963.      *  <li>IMAGE_TOOLBOX_BLEND_MULTIPLY</li>
  964.      *  <li>IMAGE_TOOLBOX_BLEND_SCREEN</li>
  965.      *  <li>IMAGE_TOOLBOX_BLEND_DIFFERENCE</li>
  966.      *  <li>IMAGE_TOOLBOX_BLEND_EXCLUSION</li>
  967.      *  <li>IMAGE_TOOLBOX_BLEND_OVERLAY</li>
  968.      * </ul>
  969.      *
  970.      * $percent:<br>
  971.      * alpha value in percent of blend effect (0 - 100)<br>
  972.      * (default = 100)
  973.      *
  974.      * @param string|integer $x Horizontal position of second image.
  975.      * @param integer $y Vertical position of second image. negative values are possible.
  976.      * @param integer $mode blend mode.
  977.      * @param integer $percent alpha value
  978.      */
  979.         function blend($x = 0, $y = 0, $mode = IMAGE_TOOLBOX_BLEND_COPY, $percent = 100) {
  980.                 if (is_string($x) || is_string($y)) {
  981.                         list($xalign, $xalign_offset) = explode(" ", $x);
  982.                         list($yalign, $yalign_offset) = explode(" ", $y);
  983.                 }
  984.                 if (is_string($x)) {
  985.                         switch ($xalign) {
  986.                                 case 'left':
  987.                                         $dst_x = 0 + $xalign_offset;
  988.                                         $src_x = 0;
  989.                                         $src_w = $this->_img['operator']['width'];
  990.                                         break;
  991.                                        
  992.                                 case 'right':
  993.                                         $dst_x = ($this->_img['main']['width'] - $this->_img['operator']['width']) + $xalign_offset;
  994.                                         $src_x = 0;
  995.                                         $src_w = $this->_img['operator']['width'];
  996.                                         break;
  997.                                        
  998.                                 case 'middle':
  999.                                 case 'center':
  1000.                                         $dst_x = (($this->_img['main']['width'] / 2) - ($this->_img['operator']['width'] / 2)) + $yalign_offset;
  1001.                                         $src_x = 0;
  1002.                                         $src_w = $this->_img['operator']['width'];
  1003.                                         break;
  1004.                         }
  1005.                 } else {
  1006.                         if ($x >= 0) {
  1007.                                 $dst_x = $x;
  1008.                                 $src_x = 0;
  1009.                                 $src_w = $this->_img['operator']['width'];
  1010.                         } else {
  1011.                                 $dst_x = 0;
  1012.                                 $src_x = abs($x);
  1013.                                 $src_w = $this->_img['operator']['width'] - $src_x;
  1014.                         }
  1015.                 }
  1016.                 if (is_string($y)) {
  1017.                         switch ($yalign) {
  1018.                                 case 'top':
  1019.                                         $dst_y = 0 + $yalign_offset;
  1020.                                         $src_y = 0;
  1021.                                         $src_h = $this->_img['operator']['height'];
  1022.                                         break;
  1023.                                        
  1024.                                 case 'bottom':
  1025.                                         $dst_y = ($this->_img['main']['height'] - $this->_img['operator']['height']) + $yalign_offset;
  1026.                                         $src_y = 0;
  1027.                                         $src_h = $this->_img['operator']['height'];
  1028.                                         break;
  1029.                                        
  1030.                                 case 'middle':
  1031.                                 case 'center':
  1032.                                         $dst_y = (($this->_img['main']['height'] / 2) - ($this->_img['operator']['height'] / 2)) + $yalign_offset;
  1033.                                         $src_y = 0;
  1034.                                         $src_h = $this->_img['operator']['height'];
  1035.                                         break;
  1036.                         }
  1037.                 } else {
  1038.                         if ($y >= 0) {
  1039.                                 $dst_y = $y;
  1040.                                 $src_y = 0;
  1041.                                 $src_h = $this->_img['operator']['height'];
  1042.                         } else {
  1043.                                 $dst_y = 0;
  1044.                                 $src_y = abs($y);
  1045.                                 $src_h = $this->_img['operator']['height'] - $src_y;
  1046.                         }
  1047.                 }
  1048.                 $this->_imageBlend($mode, $dst_x, $dst_y, $src_x, $src_y, $src_w, $src_h, $percent);
  1049.                 return true;
  1050.         }
  1051.        
  1052.         /**
  1053.      * Blend two images.
  1054.      *
  1055.      * @access private
  1056.      */
  1057.         function _imageBlend($mode, $dst_x, $dst_y, $src_x, $src_y, $src_w, $src_h, $percent) {
  1058.                 if ($mode == IMAGE_TOOLBOX_BLEND_COPY) {
  1059.                         if ($percent == 100) {
  1060.                                 imagecopy($this->_img['main']['resource'], $this->_img['operator']['resource'], $dst_x, $dst_y, $src_x, $src_y, $src_w, $src_h);
  1061.                         } else {
  1062.                                 imagecopymerge($this->_img['main']['resource'], $this->_img['operator']['resource'], $dst_x, $dst_y, $src_x, $src_y, $src_w, $src_h, $percent);
  1063.                         }
  1064.                 } else {
  1065.                         $functionname = $this->_imagecreatefunction;
  1066.                         $dummy = $functionname($src_w, $src_h);
  1067.                         for ($y=0; $y < $src_h; $y++) {
  1068.                                 for ($x=0; $x < $src_w; $x++) {
  1069.                                         $colorindex = imagecolorat($this->_img['main']['resource'], $dst_x + $x, $dst_y + $y);
  1070.                                         $colorrgb1 = imagecolorsforindex($this->_img['main']['resource'], $colorindex);
  1071.                                         $colorindex = imagecolorat($this->_img['operator']['resource'], $src_x + $x, $src_y + $y);
  1072.                                         $colorrgb2 = imagecolorsforindex($this->_img['operator']['resource'], $colorindex);
  1073.                                         $colorblend = $this->_calculateBlendvalue($mode, $colorrgb1, $colorrgb2);
  1074.                                         $newcolor = imagecolorallocate($dummy, $colorblend['red'], $colorblend['green'], $colorblend['blue']);
  1075.                                         imagesetpixel($dummy, $x, $y, $newcolor);
  1076.                                 }
  1077.                         }
  1078.                
  1079.                         $this->_img['target']['resource'] = $functionname($this->_img['main']['width'], $this->_img['main']['height']);
  1080.                         imagecopy($this->_img['target']['resource'], $this->_img['main']['resource'], 0, 0, 0, 0, $this->_img['main']['width'], $this->_img['main']['height']);
  1081.                         imagecopymerge($this->_img['target']['resource'], $dummy, $dst_x, $dst_y, $src_x, $src_y, $src_w, $src_h, $percent);
  1082.                                                                        
  1083.                         $this->_img['main']['resource'] = $this->_img['target']['resource'];
  1084.                         unset($this->_img['target']);
  1085.                 }
  1086.         }
  1087.        
  1088.         /**
  1089.      * Calculate blend values for given blend mode
  1090.      *
  1091.      * @access private
  1092.      */
  1093.         function _calculateBlendvalue($mode, $colorrgb1, $colorrgb2) {
  1094.                 switch ($mode) {
  1095.                         case IMAGE_TOOLBOX_BLEND_MULTIPLY:
  1096.                                 $c['red'] = ($colorrgb1['red'] * $colorrgb2['red']) >> 8;
  1097.                                 $c['green'] = ($colorrgb1['green'] * $colorrgb2['green']) >> 8;
  1098.                                 $c['blue'] = ($colorrgb1['blue'] * $colorrgb2['blue']) >> 8;
  1099.                                 break;
  1100.                        
  1101.                         case IMAGE_TOOLBOX_BLEND_SCREEN:
  1102.                                 $c['red'] = 255 - ((255 - $colorrgb1['red']) * (255 - $colorrgb2['red']) >> 8);
  1103.                                 $c['green'] = 255 - ((255 - $colorrgb1['green']) * (255 - $colorrgb2['green']) >> 8);
  1104.                                 $c['blue'] = 255 - ((255 - $colorrgb1['blue']) * (255 - $colorrgb2['blue']) >> 8);
  1105.                                 break;
  1106.                        
  1107.                         case IMAGE_TOOLBOX_BLEND_DIFFERENCE:
  1108.                                 $c['red'] = abs($colorrgb1['red'] - $colorrgb2['red']);
  1109.                                 $c['green'] = abs($colorrgb1['green'] - $colorrgb2['green']);
  1110.                                 $c['blue'] = abs($colorrgb1['blue'] - $colorrgb2['blue']);
  1111.                                 break;
  1112.                        
  1113.                         case IMAGE_TOOLBOX_BLEND_NEGATION:     
  1114.                                 $c['red'] = 255 - abs(255 - $colorrgb1['red'] - $colorrgb2['red']);
  1115.                                 $c['green'] = 255 - abs(255 - $colorrgb1['green'] - $colorrgb2['green']);
  1116.                                 $c['blue'] = 255 - abs(255 - $colorrgb1['blue'] - $colorrgb2['blue']);
  1117.                                 break;
  1118.                                
  1119.                         case IMAGE_TOOLBOX_BLEND_EXCLUTION:    
  1120.                                 $c['red'] = $colorrgb1['red'] + $colorrgb2['red'] - (($colorrgb1['red'] * $colorrgb2['red']) >> 7);
  1121.                                 $c['green'] = $colorrgb1['green'] + $colorrgb2['green'] - (($colorrgb1['green'] * $colorrgb2['green']) >> 7);
  1122.                                 $c['blue'] = $colorrgb1['blue'] + $colorrgb2['blue'] - (($colorrgb1['blue'] * $colorrgb2['blue']) >> 7);
  1123.                                 break;
  1124.                                
  1125.                         case IMAGE_TOOLBOX_BLEND_OVERLAY:                      
  1126.                                 if ($colorrgb1['red'] < 128) {
  1127.                                         $c['red']= ($colorrgb1['red'] * $colorrgb2['red']) >> 7;
  1128.                                 } else {
  1129.                                         $c['red'] = 255 - ((255 - $colorrgb1['red']) * (255 - $colorrgb2['red']) >> 7);
  1130.                                 }
  1131.                                 if ($colorrgb1['green'] < 128) {
  1132.                                         $c['green'] = ($colorrgb1['green'] * $colorrgb2['green']) >> 7;
  1133.                                 } else {
  1134.                                         $c['green'] = 255 - ((255 - $colorrgb1['green']) * (255 - $colorrgb2['green']) >> 7);
  1135.                                 }
  1136.                                 if ($colorrgb1['blue'] < 128) {
  1137.                                         $c['blue'] = ($colorrgb1['blue'] * $colorrgb2['blue']) >> 7;
  1138.                                 } else {
  1139.                                         $c['blue'] = 255 - ((255 - $colorrgb1['blue']) * (255 - $colorrgb2['blue']) >> 7);
  1140.                                 }
  1141.                                 break;
  1142.                                
  1143.                         default:
  1144.                                 break;
  1145.                 }
  1146.                 return $c;
  1147.         }
  1148.        
  1149.         /**
  1150.      * convert iso character coding to unicode (PHP conform)
  1151.      * needed for TTF text generation of special characters (Latin-2)
  1152.      *
  1153.      * @access private
  1154.      */
  1155.         function _iso2uni($isoline) {
  1156.                 $iso2uni = array(
  1157.                         173 => "&#161;",
  1158.                         155 => "&#162;",
  1159.                         156 => "&#163;",
  1160.                         15 => "&#164;",
  1161.                         157 => "&#165;",
  1162.                         124 => "&#166;",
  1163.                         21 => "&#167;",
  1164.                         249 => "&#168;",
  1165.                         184 => "&#169;",
  1166.                         166 => "&#170;",
  1167.                         174 => "&#171;",
  1168.                         170 => "&#172;",
  1169.                         169 => "&#174;",
  1170.                         238 => "&#175;",
  1171.                         248 => "&#176;",
  1172.                         241 => "&#177;",
  1173.                         253 => "&#178;",
  1174.                         252 => "&#179;",
  1175.                         239 => "&#180;",
  1176.                         230 => "&#181;",
  1177.                         20 => "&#182;",
  1178.                         250 => "&#183;",
  1179.                         247 => "&#184;",
  1180.                         251 => "&#185;",
  1181.                         167 => "&#186;",
  1182.                         175 => "&#187;",
  1183.                         172 => "&#188;",
  1184.                         171 => "&#189;",
  1185.                         243 => "&#190;",
  1186.                         168 => "&#191;",
  1187.                         183 => "&#192;",
  1188.                         181 => "&#193;",
  1189.                         182 => "&#194;",
  1190.                         199 => "&#195;",
  1191.                         142 => "&#196;",
  1192.                         143 => "&#197;",
  1193.                         146 => "&#198;",
  1194.                         128 => "&#199;",
  1195.                         212 => "&#200;",
  1196.                         144 => "&#201;",
  1197.                         210 => "&#202;",
  1198.                         211 => "&#203;",
  1199.                         141 => "&#204;",
  1200.                         161 => "&#205;",
  1201.                         140 => "&#206;",
  1202.                         139 => "&#207;",
  1203.                         209 => "&#208;",
  1204.                         165 => "&#209;",
  1205.                         227 => "&#210;",
  1206.                         224 => "&#211;",
  1207.                         226 => "&#212;",
  1208.                         229 => "&#213;",
  1209.                         153 => "&#214;",
  1210.                         158 => "&#215;",
  1211.                         157 => "&#216;",
  1212.                         235 => "&#217;",
  1213.                         233 => "&#218;",
  1214.                         234 => "&#219;",
  1215.                         154 => "&#220;",
  1216.                         237 => "&#221;",
  1217.                         232 => "&#222;",
  1218.                         225 => "&#223;",
  1219.                         133 => "&#224;",
  1220.                         160 => "&#225;",
  1221.                         131 => "&#226;",
  1222.                         198 => "&#227;",
  1223.                         132 => "&#228;",
  1224.                         134 => "&#229;",
  1225.                         145 => "&#230;",
  1226.                         135 => "&#231;",
  1227.                         138 => "&#232;",
  1228.                         130 => "&#233;",
  1229.                         136 => "&#234;",
  1230.                         137 => "&#235;",
  1231.                         141 => "&#236;",
  1232.                         161 => "&#237;",
  1233.                         140 => "&#238;",
  1234.                         139 => "&#239;",
  1235.                         208 => "&#240;",
  1236.                         164 => "&#241;",
  1237.                         149 => "&#242;",
  1238.                         162 => "&#243;",
  1239.                         147 => "&#244;",
  1240.                         228 => "&#245;",
  1241.                         148 => "&#246;",
  1242.                         246 => "&#247;",
  1243.                         155 => "&#248;",
  1244.                         151 => "&#249;",
  1245.                         163 => "&#250;",
  1246.                         150 => "&#251;",
  1247.                         129 => "&#252;",
  1248.                         236 => "&#253;",
  1249.                         231 => "&#254;",
  1250.                         152 => "&#255;"
  1251.                 );
  1252.                 for ($i=0; $i < strlen($isoline); $i++){
  1253.                         $thischar = substr($isoline, $i, 1);
  1254.                         $new = $iso2uni[ord($thischar)];
  1255.                         $uniline .= ($new != "") ? $new : $thischar;
  1256.                 }
  1257.                 return $uniline;
  1258.         }
  1259.  
  1260.         /**
  1261.      * Writes text over the image
  1262.      *
  1263.      * only TTF fonts are supported at the moment
  1264.      *
  1265.      * $x:<br>
  1266.      * You can also use the following keywords ('left', 'center' or 'middle', 'right').<br>
  1267.      * Additionally you can specify an offset in pixel with the keywords like this 'left +10'.<br>
  1268.      * (default = 0)
  1269.      *
  1270.      * $y:<br>
  1271.      * You can also use the following keywords ('top', 'center' or 'middle', 'bottom').<br>
  1272.      * Additionally you can specify an offset in pixel with the keywords like this 'bottom -10'.<br>
  1273.      * (default = 0)
  1274.      *
  1275.      * @param string $text text to be generated.
  1276.      * @param string $font TTF fontfile to be used. (relative paths are ok).
  1277.      * @param integer $size textsize.
  1278.      * @param string $color textcolor in hexformat (e.g. '#FF0000').
  1279.      * @param string|integer $x horizontal postion in pixel.
  1280.      * @param string|integer $y vertical postion in pixel.
  1281.      * @param integer $angle rotation of the text.
  1282.      */
  1283.         function addText($text, $font, $size, $color, $x, $y, $angle = 0) {
  1284.                 global $HTTP_SERVER_VARS;
  1285.                
  1286.                 if (substr($font, 0, 1) == DIRECTORY_SEPARATOR || (substr($font, 1, 1) == ":" && (substr($font, 2, 1) == "\\" || substr($font, 2, 1) == "/"))) {
  1287.                         $prepath = '';
  1288.                 } else {
  1289.                         $prepath = substr($HTTP_SERVER_VARS['SCRIPT_FILENAME'], 0, strrpos($HTTP_SERVER_VARS['SCRIPT_FILENAME'], DIRECTORY_SEPARATOR)) . DIRECTORY_SEPARATOR;
  1290.                 }
  1291.                 $text = $this->_iso2uni($text);
  1292.                 if (is_string($x) || is_string($y)) {
  1293.                         $textsize = imagettfbbox($size, $angle, $prepath.$font, $text);
  1294.                         $textwidth = abs($textsize[2]);
  1295.                         $textheight = abs($textsize[7]);
  1296.                         list($xalign, $xalign_offset) = explode(" ", $x);
  1297.                         list($yalign, $yalign_offset) = explode(" ", $y);
  1298.                 }
  1299.                 if (is_string($x)) {
  1300.                         switch ($xalign) {
  1301.                                 case 'left':
  1302.                                         $x = 0 + $xalign_offset;
  1303.                                         break;
  1304.                                        
  1305.                                 case 'right':
  1306.                                         $x = ($this->_img['main']['width'] - $textwidth) + $xalign_offset;
  1307.                                         break;
  1308.                                        
  1309.                                 case 'middle':
  1310.                                 case 'center':
  1311.                                         $x = (($this->_img['main']['width'] - $textwidth) / 2) + $xalign_offset;
  1312.                                         break;
  1313.                         }
  1314.                 }
  1315.                 if (is_string($y)) {
  1316.                         switch ($yalign) {
  1317.                                 case 'top':
  1318.                                         $y = (0 + $textheight) + $yalign_offset;
  1319.                                         break;
  1320.                                        
  1321.                                 case 'bottom':
  1322.                                         $y = ($this->_img['main']['height']) + $yalign_offset;
  1323.                                         break;
  1324.                                        
  1325.                                 case 'middle':
  1326.                                 case 'center':
  1327.                                         $y = ((($this->_img['main']['height'] - $textheight) / 2) + $textheight) + $yalign_offset;
  1328.                                         break;
  1329.                         }
  1330.                 }
  1331.                 imagettftext($this->_img['main']['resource'], $size, $angle, $x, $y, $this->_hexToPHPColor($color), $prepath . $font, $text);
  1332.                 return true;
  1333.         }
  1334.        
  1335.         /**
  1336.      * workaround function for bicubic resizing. works well for downsizing only. VERY slow. taken from php.net comments
  1337.      *
  1338.      * @access private
  1339.      */
  1340.         function _imageCopyResampledWorkaround(&$dst_img, &$src_img, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h) {
  1341.                 /*
  1342.                 for ($i = 0; $i < imagecolorstotal($src_img); $i++)
  1343.                 {
  1344.                         $colors = ImageColorsForIndex ($src_img, $i);
  1345.                         ImageColorAllocate ($dst_img, $colors['red'],$colors['green'], $colors['blue']);
  1346.                 }
  1347.                 */
  1348.                 $scaleX = ($src_w - 1) / $dst_w;
  1349.                 $scaleY = ($src_h - 1) / $dst_h;
  1350.  
  1351.                 $scaleX2 = $scaleX / 2.0;
  1352.                 $scaleY2 = $scaleY / 2.0;
  1353.  
  1354.                 for ($j = $src_y; $j < $src_y + $dst_h; $j++) {
  1355.                         $sY = $j * $scaleY;
  1356.                         for ($i = $src_x; $i < $src_x + $dst_w; $i++) {
  1357.                                 $sX = $i * $scaleX;
  1358.  
  1359.                                 $c1 = ImageColorsForIndex($src_img, ImageColorAt($src_img, (int) $sX, (int) $sY + $scaleY2));
  1360.                                 $c2 = ImageColorsForIndex($src_img, ImageColorAt($src_img, (int) $sX, (int) $sY));
  1361.                                 $c3 = ImageColorsForIndex($src_img, ImageColorAt($src_img, (int) $sX + $scaleX2, (int) $sY + $scaleY2));
  1362.                                 $c4 = ImageColorsForIndex($src_img, ImageColorAt($src_img, (int) $sX + $scaleX2, (int) $sY));
  1363.  
  1364.                                 $red = (integer) (($c1['red'] + $c2['red'] + $c3['red'] + $c4['red']) / 4);
  1365.                                 $green = (integer) (($c1['green'] + $c2['green'] + $c3['green'] + $c4['green']) / 4);
  1366.                                 $blue = (integer) (($c1['blue'] + $c2['blue'] + $c3['blue'] + $c4['blue']) / 4);
  1367.  
  1368.                                 $color = ImageColorClosest ($dst_img, $red, $green,$blue);
  1369.                                 ImageSetPixel ($dst_img, $dst_x + $i - $src_x, $dst_y + $j - $src_y,$color);
  1370.                         }
  1371.                 }
  1372.         }
  1373.  
  1374.         /**
  1375.      * alternative workaround function for bicubic resizing. works well for downsizing and upsizing. VERY VERY slow. taken from php.net comments
  1376.      *
  1377.      * @access private
  1378.      */
  1379.         function _imageCopyResampledWorkaround2(&$dst_img, &$src_img, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h) {
  1380.                 ImagePaletteCopy ($dst_img, $src_img);
  1381.                 $rX = $src_w / $dst_w;
  1382.                 $rY = $src_h / $dst_h;
  1383.                 $w = 0;
  1384.                 for ($y = $dst_y; $y < $dst_h; $y++) {
  1385.                         $ow = $w; $w = round(($y + 1) * $rY);
  1386.                         $t = 0;
  1387.                         for ($x = $dst_x; $x < $dst_w; $x++) {
  1388.                                 $r = $g = $b = 0; $a = 0;
  1389.                                 $ot = $t; $t = round(($x + 1) * $rX);
  1390.                                 for ($u = 0; $u < ($w - $ow); $u++) {
  1391.                                         for ($p = 0; $p < ($t - $ot); $p++) {
  1392.                                                 $c = ImageColorsForIndex ($src_img, ImageColorAt ($src_img, $ot + $p, $ow + $u));
  1393.                                                 $r += $c['red'];
  1394.                                                 $g += $c['green'];
  1395.                                                 $b += $c['blue'];
  1396.                                                 $a++;
  1397.                                         }
  1398.                                 }
  1399.                                 ImageSetPixel ($dst_img, $x, $y, ImageColorClosest ($dst_img, $r / $a, $g / $a, $b / $a));
  1400.                         }
  1401.                 }
  1402.         }
  1403. }