[ Index ]

PHP Cross Reference of phpwcms V1.5.0 _r431 (28.01.12)

title

Body

[close]

/include/inc_lib/ -> helper.image.php (source)

   1  <?php
   2  /*************************************************************************************
   3     Copyright notice
   4     
   5     (c) 2002-2012 Oliver Georgi <oliver@phpwcms.de> // All rights reserved.
   6   
   7     This script is part of PHPWCMS. The PHPWCMS web content management system is
   8     free software; you can redistribute it and/or modify it under the terms of
   9     the GNU General Public License as published by the Free Software Foundation;
  10     either version 2 of the License, or (at your option) any later version.
  11    
  12     The GNU General Public License can be found at http://www.gnu.org/copyleft/gpl.html
  13     A copy is found in the textfile GPL.txt and important notices to the license 
  14     from the author is found in LICENSE.txt distributed with these scripts.
  15    
  16     This script is distributed in the hope that it will be useful, but WITHOUT ANY 
  17     WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
  18     PARTICULAR PURPOSE.  See the GNU General Public License for more details.
  19   
  20     This file incorporates work covered by the following copyright and  
  21     license notice:
  22  
  23        Copyright (c) 2008 - 2012, EllisLab, Inc. (http://ellislab.com/)
  24   
  25        Parts of this source file is subject to the Open Software License (OSL 3.0).
  26        It is also available through the world wide web at this URL:
  27        http://opensource.org/licenses/OSL-3.0
  28     
  29     This copyright notice MUST APPEAR in all copies of the script!
  30  
  31  *************************************************************************************/
  32  
  33  // ----------------------------------------------------------------
  34  // obligate check for phpwcms constants
  35  if (!defined('PHPWCMS_ROOT')) {
  36     die("You Cannot Access This Script Directly, Have a Nice Day.");
  37  }
  38  // ----------------------------------------------------------------
  39  
  40  /**
  41   * Image Manipulation class
  42   *
  43   * Taken from CodeIgniter and adopted for use in phpwcms.
  44   *
  45   * @author        EllisLab Dev Team
  46   * @copyright    Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
  47   * @author        Oliver Georgi <oliver@phpwcms.de>
  48   * @copyright    Copyright (c) 2011, Oliver Georgi (http://phpwcms.de/)
  49   */
  50  class Phpwcms_Image_lib {
  51  
  52      var $image_library        = 'gd2';    // Can be:  imagemagick, netpbm, gd, gd2
  53      var $library_path        = '';
  54      var $dynamic_output        = FALSE;    // Whether to send to browser or write to disk
  55      var $source_image        = '';
  56      var $new_image            = '';
  57      var $width                = '';
  58      var $height                = '';
  59      var $quality            = '90';
  60      var $create_thumb        = FALSE;
  61      var $thumb_marker        = '_thumb';
  62      var $maintain_ratio        = TRUE;        // Whether to maintain aspect ratio when resizing or use hard values
  63      var $master_dim            = 'auto';    // auto, height, or width.  Determines what to use as the master dimension
  64      var $rotation_angle        = '';
  65      var $x_axis                = '';
  66      var    $y_axis                = '';
  67      var $sharpen            = FALSE;
  68      var $target_ext            = 'jpg';
  69  
  70      // Watermark Vars
  71      var $wm_text            = '';            // Watermark text if graphic is not used
  72      var $wm_type            = 'text';        // Type of watermarking.  Options:  text/overlay
  73      var $wm_x_transp        = 4;
  74      var $wm_y_transp        = 4;
  75      var $wm_overlay_path    = '';            // Watermark image path
  76      var $wm_font_path        = '';            // TT font
  77      var $wm_font_size        = 17;            // Font size (different versions of GD will either use points or pixels)
  78      var $wm_vrt_alignment    = 'B';            // Vertical alignment:   T M B
  79      var $wm_hor_alignment    = 'C';            // Horizontal alignment: L R C
  80      var $wm_padding            = 0;            // Padding around text
  81      var $wm_hor_offset        = 0;            // Lets you push text to the right
  82      var $wm_vrt_offset        = 0;            // Lets you push  text down
  83      var $wm_font_color        = '#ffffff';    // Text color
  84      var $wm_shadow_color    = '';            // Dropshadow color
  85      var $wm_shadow_distance    = 2;            // Dropshadow distance
  86      var $wm_opacity            = 50;            // Image opacity: 1 - 100  Only works with image
  87  
  88      // Private Vars
  89      var $source_folder        = '';
  90      var $dest_folder        = '';
  91      var $mime_type            = '';
  92      var $orig_width            = '';
  93      var $orig_height        = '';
  94      var $source_ext            = '';
  95      var $image_type            = '';
  96      var $size_str            = '';
  97      var $full_src_path        = '';
  98      var $full_dst_path        = '';
  99      var $create_fnc            = 'imagecreatetruecolor';
 100      var $copy_fnc            = 'imagecopyresampled';
 101      var $error_msg            = array();
 102      var $wm_use_drop_shadow    = FALSE;
 103      var $wm_use_truetype    = FALSE;
 104      var $image_cache        = array();
 105      var $image_current_vals    = array();
 106      
 107      // Language strings
 108      var $lang                = array(
 109          'imglib_source_image_required'        => "You must specify a source image in your preferences.",
 110          'imglib_gd_required'                => "The GD image library is required for this feature.",
 111          'imglib_gd_required_for_props'        => "Your server must support the GD image library in order to determine the image properties.",
 112          'imglib_unsupported_imagecreate'    => "Your server does not support the GD function required to process this type of image.",
 113          'imglib_gif_not_supported'            => "GIF images are often not supported due to licensing restrictions.  You may have to use JPG or PNG images instead.",
 114          'imglib_jpg_not_supported'            => "JPG images are not supported.",
 115          'imglib_png_not_supported'            => "PNG images are not supported.",
 116          'imglib_jpg_or_png_required'        => "The image resize protocol specified in your preferences only works with JPEG or PNG image types.",
 117          'imglib_copy_error'                    => "An error was encountered while attempting to replace the file.  Please make sure your file directory is writable.",
 118          'imglib_rotate_unsupported'            => "Image rotation does not appear to be supported by your server.",
 119          'imglib_libpath_invalid'            => "The path to your image library is not correct.  Please set the correct path in your image preferences.",
 120          'imglib_image_process_failed'        => "Image processing failed.  Please verify that your server supports the chosen protocol and that the path to your image library is correct.",
 121          'imglib_rotation_angle_required'    => "An angle of rotation is required to rotate the image.",
 122          'imglib_writing_failed_gif'            => "GIF image.",
 123          'imglib_invalid_path'                => "The path to the image is not correct.",
 124          'imglib_copy_failed'                => "The image copy routine failed.",
 125          'imglib_missing_font'                => "Unable to find a font to use.",
 126          'imglib_save_failed'                => "Unable to save the image.  Please make sure the image and file directory are writable."
 127      );
 128      var $lang_localized        = FALSE;        // set to TRUE if overwritten once
 129  
 130      /**
 131       * Constructor
 132       *
 133       * @param    string
 134       * @return    void
 135       */
 136  	public function __construct($props = array())
 137      {
 138          if (count($props) > 0)
 139          {
 140              $this->initialize($props);
 141          }
 142      }
 143  
 144      // --------------------------------------------------------------------
 145  
 146      /**
 147       * Initialize image properties
 148       *
 149       * Resets values in case this class is used in a loop.
 150       *
 151       * @return    void
 152       */
 153  	function clear()
 154      {
 155          $props = array(
 156              'library_path',
 157              'source_image',
 158              'new_image',
 159              'width',
 160              'height',
 161              'rotation_angle',
 162              'x_axis',
 163              'y_axis',
 164              'wm_text',
 165              'wm_overlay_path',
 166              'wm_font_path',
 167              'wm_shadow_color',
 168              'source_folder',
 169              'dest_folder',
 170              'mime_type',
 171              'orig_width',
 172              'orig_height',
 173              'image_type',
 174              'size_str',
 175              'full_src_path',
 176              'full_dst_path'
 177          );
 178  
 179          foreach ($props as $val)
 180          {
 181              $this->$val = '';
 182          }
 183  
 184          $this->image_library         = 'gd2';
 185          $this->dynamic_output         = FALSE;
 186          $this->quality                 = '90';
 187          $this->create_thumb         = FALSE;
 188          $this->thumb_marker         = '_thumb';
 189          $this->maintain_ratio         = TRUE;
 190          $this->master_dim             = 'auto';
 191          $this->wm_type                 = 'text';
 192          $this->wm_x_transp             = 4;
 193          $this->wm_y_transp             = 4;
 194          $this->wm_font_size         = 17;
 195          $this->wm_vrt_alignment     = 'B';
 196          $this->wm_hor_alignment     = 'C';
 197          $this->wm_padding             = 0;
 198          $this->wm_hor_offset         = 0;
 199          $this->wm_vrt_offset         = 0;
 200          $this->wm_font_color        = '#ffffff';
 201          $this->wm_shadow_distance     = 2;
 202          $this->wm_opacity             = 50;
 203          $this->create_fnc             = 'imagecreatetruecolor';
 204          $this->copy_fnc             = 'imagecopyresampled';
 205          $this->error_msg             = array();
 206          $this->wm_use_drop_shadow     = FALSE;
 207          $this->wm_use_truetype         = FALSE;
 208          $this->sharpen                = FALSE;
 209      }
 210  
 211      // --------------------------------------------------------------------
 212  
 213      /**
 214       * initialize image preferences
 215       *
 216       * @param    array
 217       * @return    bool
 218       */
 219  	function initialize($props = array())
 220      {
 221          /*
 222           * Convert array elements into class variables
 223           */
 224          if (count($props) > 0)
 225          {
 226              foreach ($props as $key => $val)
 227              {
 228                  if (property_exists($this, $key))
 229                  {
 230                      if ($key === 'wm_font_color' || $key === 'wm_shadow_color')
 231                      {
 232                          if (preg_match('/^#?([0-9a-f]{3}|[0-9a-f]{6})$/i', $val, $matches))
 233                          {
 234                              /* $matches[1] contains our hex color value, but it might be
 235                               * both in the full 6-length format or the shortened 3-length
 236                               * value.
 237                               * We'll later need the full version, so we keep it if it's
 238                               * already there and if not - we'll convert to it. We can
 239                               * access string characters by their index as in an array,
 240                               * so we'll do that and use concatenation to form the final
 241                               * value:
 242                               */
 243                              $val = (strlen($matches[1]) === 6)
 244                                  ? '#'.$matches[1]
 245                                  : '#'.$matches[1][0].$matches[1][0].$matches[1][1].$matches[1][1].$matches[1][2].$matches[1][2];
 246                          }
 247                          else
 248                          {
 249                              continue;
 250                          }
 251                      }
 252  
 253                      $this->$key = $val;
 254                  }
 255              }
 256          }
 257  
 258          /*
 259           * Is there a source image?
 260           *
 261           * If not, there's no reason to continue
 262           *
 263           */
 264          if ($this->source_image == '')
 265          {
 266              $this->set_error('imglib_source_image_required');
 267              return FALSE;    
 268          }
 269  
 270          /*
 271           * Is getimagesize() Available?
 272           *
 273           * We use it to determine the image properties (width/height).
 274           * Note:  We need to figure out how to determine image
 275           * properties using ImageMagick and NetPBM
 276           *
 277           */
 278          if ( ! function_exists('getimagesize'))
 279          {
 280              $this->set_error('imglib_gd_required_for_props');
 281              return FALSE;
 282          }
 283  
 284          $this->image_library = strtolower($this->image_library);
 285  
 286          /*
 287           * Set the full server path
 288           *
 289           * The source image may or may not contain a path.
 290           * Either way, we'll try use realpath to generate the
 291           * full server path in order to more reliably read it.
 292           *
 293           */
 294          if (function_exists('realpath') AND @realpath($this->source_image) !== FALSE)
 295          {
 296              $full_source_path = str_replace("\\", "/", realpath($this->source_image));
 297          }
 298          else
 299          {
 300              $full_source_path = $this->source_image;
 301          }
 302  
 303          $x = explode('/', $full_source_path);
 304          $this->source_image = end($x);
 305          $this->source_folder = str_replace($this->source_image, '', $full_source_path);
 306  
 307          // Set the Image Properties
 308          if ( ! $this->get_image_properties($this->source_folder.$this->source_image))
 309          {
 310              return FALSE;    
 311          }
 312  
 313          $this->source_ext = $this->explode_name($this->source_image, TRUE);    
 314  
 315          /*
 316           * Assign the "new" image name/path
 317           *
 318           * If the user has set a "new_image" name it means
 319           * we are making a copy of the source image. If not
 320           * it means we are altering the original.  We'll
 321           * set the destination filename and path accordingly.
 322           *
 323           */
 324          if ($this->new_image == '')
 325          {
 326              $this->dest_image = $this->source_image;
 327              $this->dest_folder = $this->source_folder;
 328          }
 329          else
 330          {
 331              if (strpos($this->new_image, '/') === FALSE)
 332              {
 333                  $this->dest_folder = $this->source_folder;
 334                  $this->dest_image = $this->new_image;
 335              }
 336              else
 337              {
 338                  if (function_exists('realpath') AND @realpath($this->new_image) !== FALSE)
 339                  {
 340                      $full_dest_path = str_replace("\\", "/", realpath($this->new_image));
 341                  }
 342                  else
 343                  {
 344                      $full_dest_path = $this->new_image;
 345                  }
 346  
 347                  // Is there a file name?
 348                  if ( ! preg_match("#\.(jpg|jpeg|gif|png)$#i", $full_dest_path))
 349                  {
 350                      $this->dest_folder = $full_dest_path.'/';
 351                      $this->dest_image = $this->source_image;
 352                  }
 353                  else
 354                  {
 355                      $x = explode('/', $full_dest_path);
 356                      $this->dest_image = end($x);
 357                      $this->dest_folder = str_replace($this->dest_image, '', $full_dest_path);
 358                  }
 359              }
 360          }
 361  
 362          /*
 363           * Compile the finalized filenames/paths
 364           *
 365           * We'll create two master strings containing the
 366           * full server path to the source image and the
 367           * full server path to the destination image.
 368           * We'll also split the destination image name
 369           * so we can insert the thumbnail marker if needed.
 370           *
 371           */
 372          if ($this->create_thumb === FALSE OR $this->thumb_marker == '')
 373          {
 374              $this->thumb_marker = '';
 375          }
 376          
 377          $xp    = $this->explode_name($this->dest_image);
 378  
 379          $filename = $xp['name'];
 380          $file_ext = $xp['ext'];
 381  
 382          $this->full_src_path = $this->source_folder.$this->source_image;
 383          $this->full_dst_path = $this->dest_folder.$filename.$this->thumb_marker.$file_ext;
 384  
 385          /*
 386           * Should we maintain image proportions?
 387           *
 388           * When creating thumbs or copies, the target width/height
 389           * might not be in correct proportion with the source
 390           * image's width/height.  We'll recalculate it here.
 391           *
 392           */
 393          if ($this->maintain_ratio === TRUE && ($this->width != '' AND $this->height != ''))
 394          {
 395              $this->image_reproportion();
 396          }
 397  
 398          /*
 399           * Was a width and height specified?
 400           *
 401           * If the destination width/height was
 402           * not submitted we will use the values
 403           * from the actual file
 404           *
 405           */
 406          if ($this->width == '')
 407              $this->width = $this->orig_width;
 408  
 409          if ($this->height == '')
 410              $this->height = $this->orig_height;
 411  
 412          // Set the quality
 413          $this->quality = trim(str_replace("%", "", $this->quality));
 414  
 415          if ($this->quality == '' OR $this->quality == 0 OR ! is_numeric($this->quality))
 416              $this->quality = 90;
 417  
 418          // Set the x/y coordinates
 419          $this->x_axis = ($this->x_axis == '' OR ! is_numeric($this->x_axis)) ? 0 : $this->x_axis;
 420          $this->y_axis = ($this->y_axis == '' OR ! is_numeric($this->y_axis)) ? 0 : $this->y_axis;
 421  
 422          // Watermark-related Stuff...
 423          if ($this->wm_overlay_path != '')
 424          {
 425              $this->wm_overlay_path = str_replace("\\", "/", realpath($this->wm_overlay_path));
 426          }
 427  
 428          if ($this->wm_shadow_color != '')
 429          {
 430              $this->wm_use_drop_shadow = TRUE;
 431          }
 432          elseif ($this->wm_use_drop_shadow == TRUE AND $this->wm_shadow_color == '')
 433          {
 434              $this->wm_use_drop_shadow = FALSE;
 435          }
 436  
 437          if ($this->wm_font_path != '')
 438          {
 439              $this->wm_use_truetype = TRUE;
 440          }
 441  
 442          return TRUE;
 443      }
 444  
 445      // --------------------------------------------------------------------
 446  
 447      /**
 448       * Image Resize
 449       *
 450       * This is a wrapper function that chooses the proper
 451       * resize function based on the protocol specified
 452       *
 453       * @return    bool
 454       */
 455  	function resize()
 456      {
 457          $protocol = 'image_process_' . ( $this->image_library == 'gd2' ? 'gd' : $this->image_library );
 458  
 459          return $this->$protocol('resize');
 460      }
 461      
 462      /**
 463       * Image Centered Crop and Resize 
 464       *
 465       * This is a wrapper function that chooses the proper
 466       * cropping and resize function based on the protocol specified
 467       * but only available for ImageMagick
 468       *
 469       * @return    bool
 470       */
 471  	function crop_centered_resize()
 472      {
 473          $protocol    = 'image_process_' . ( $this->image_library == 'gd2' ? 'gd' : $this->image_library );
 474          $action        = $this->image_library == 'imagemagick' ? 'crop-resize-center' : 'crop';
 475  
 476          return $this->$protocol($action);
 477      }
 478  
 479      // --------------------------------------------------------------------
 480  
 481      /**
 482       * Image Crop
 483       *
 484       * This is a wrapper function that chooses the proper
 485       * cropping function based on the protocol specified
 486       *
 487       * @return    bool
 488       */
 489  	function crop()
 490      {
 491          $protocol = 'image_process_' . ( $this->image_library == 'gd2' ? 'gd' : $this->image_library );
 492  
 493          return $this->$protocol('crop');
 494      }
 495  
 496      // --------------------------------------------------------------------
 497  
 498      /**
 499       * Image Rotate
 500       *
 501       * This is a wrapper function that chooses the proper
 502       * rotation function based on the protocol specified
 503       *
 504       * @return    bool
 505       */
 506  	function rotate()
 507      {
 508          // Allowed rotation values
 509          $degs = array(90, 180, 270, 'vrt', 'hor');
 510  
 511          if ($this->rotation_angle == '' OR ! in_array($this->rotation_angle, $degs))
 512          {
 513              $this->set_error('imglib_rotation_angle_required');
 514              return FALSE;    
 515          }
 516  
 517          // Reassign the width and height
 518          if ($this->rotation_angle == 90 OR $this->rotation_angle == 270)
 519          {
 520              $this->width    = $this->orig_height;
 521              $this->height    = $this->orig_width;
 522          }
 523          else
 524          {
 525              $this->width    = $this->orig_width;
 526              $this->height    = $this->orig_height;
 527          }
 528  
 529  
 530          // Choose resizing function
 531          if ($this->image_library == 'imagemagick' OR $this->image_library == 'netpbm')
 532          {
 533              $protocol = 'image_process_'.$this->image_library;
 534  
 535              return $this->$protocol('rotate');
 536          }
 537  
 538          if ($this->rotation_angle == 'hor' OR $this->rotation_angle == 'vrt')
 539          {
 540              return $this->image_mirror_gd();
 541          }
 542          else
 543          {
 544              return $this->image_rotate_gd();
 545          }
 546      }
 547  
 548      // --------------------------------------------------------------------
 549  
 550      /**
 551       * Image Process Using GD/GD2
 552       *
 553       * This function will resize or crop
 554       *
 555       * @param    string
 556       * @return    bool
 557       */
 558  	function image_process_gd($action = 'resize')
 559      {
 560          $v2_override = FALSE;
 561  
 562          // If the target width/height match the source, AND if the new file name is not equal to the old file name
 563          // we'll simply make a copy of the original with the new name... assuming dynamic rendering is off.
 564          if ($this->dynamic_output === FALSE AND $this->orig_width == $this->width AND $this->orig_height == $this->height)
 565          {
 566              if ($this->source_image != $this->new_image AND @copy($this->full_src_path, $this->full_dst_path))
 567              {
 568                  @chmod($this->full_dst_path, 0666);
 569              }
 570  
 571              return TRUE;
 572          }
 573  
 574          // Let's set up our values based on the action
 575          if ($action == 'crop')
 576          {
 577              //  Reassign the source width/height if cropping
 578              $this->orig_width  = $this->width;
 579              $this->orig_height = $this->height;
 580  
 581              // GD 2.0 has a cropping bug so we'll test for it
 582              if ($this->gd_version() !== FALSE)
 583              {
 584                  $gd_version = str_replace('0', '', $this->gd_version());
 585                  $v2_override = ($gd_version == 2) ? TRUE : FALSE;
 586              }
 587          }
 588          else
 589          {
 590              // If resizing the x/y axis must be zero
 591              $this->x_axis = 0;
 592              $this->y_axis = 0;
 593          }
 594  
 595          //  Create the image handle
 596          if ( ! ($src_img = $this->image_create_gd()))
 597          {
 598              return FALSE;
 599          }
 600  
 601          //  Create The Image
 602          //
 603          //  old conditional which users report cause problems with shared GD libs who report themselves as "2.0 or greater"
 604          //  it appears that this is no longer the issue that it was in 2004, so we've removed it, retaining it in the comment
 605          //  below should that ever prove inaccurate.
 606          //
 607          //  if ($this->image_library == 'gd2' AND function_exists('imagecreatetruecolor') AND $v2_override == FALSE)
 608          if ($this->image_library == 'gd2' AND function_exists('imagecreatetruecolor'))
 609          {
 610              $create    = 'imagecreatetruecolor';
 611              $copy    = 'imagecopyresampled';
 612          }
 613          else
 614          {
 615              $create    = 'imagecreate';
 616              $copy    = 'imagecopyresized';
 617          }
 618  
 619          $dst_img = $create($this->width, $this->height);
 620  
 621          if ($this->image_type == 3) // png we can actually preserve transparency
 622          {
 623              imagealphablending($dst_img, FALSE);
 624              imagesavealpha($dst_img, TRUE);
 625          }
 626  
 627          $copy($dst_img, $src_img, 0, 0, $this->x_axis, $this->y_axis, $this->width, $this->height, $this->orig_width, $this->orig_height);
 628  
 629          //  Show the image
 630          if ($this->dynamic_output == TRUE)
 631          {
 632              $this->image_display_gd($dst_img);
 633          }
 634          else
 635          {
 636              // Or save it
 637              if ( ! $this->image_save_gd($dst_img))
 638              {
 639                  return FALSE;
 640              }
 641          }
 642  
 643          //  Kill the file handles
 644          imagedestroy($dst_img);
 645          imagedestroy($src_img);
 646  
 647          // Set the file to 777
 648          @chmod($this->full_dst_path, 0666);
 649  
 650          return TRUE;
 651      }
 652  
 653      // --------------------------------------------------------------------
 654  
 655      /**
 656       * Image Process Using ImageMagick
 657       *
 658       * This function will resize, crop or rotate
 659       *
 660       * @param    string
 661       * @return    bool
 662       */
 663  	function image_process_imagemagick($action = 'resize')
 664      {
 665          //  Do we have a vaild library path?
 666          if ($this->library_path == '')
 667          {
 668              $this->set_error('imglib_libpath_invalid');
 669              return FALSE;
 670          }
 671  
 672          if ( ! preg_match("/convert$/i", $this->library_path))
 673          {
 674              $this->library_path = rtrim($this->library_path, '/').'/convert';
 675          }
 676  
 677          // Execute the command
 678          $cmd  = $this->library_path;
 679          if($this->target_ext == 'jpg')
 680          {
 681              $cmd .= ' -colorspace RGB -type TrueColor';
 682          }
 683          elseif($this->target_ext == 'png')
 684          {
 685              $cmd .= ' -colorspace RGB';
 686          }
 687          elseif($this->target_ext == 'gif')
 688          {
 689              $cmd .= ' -colors 256';
 690          }
 691          $cmd .= ' -quality '.$this->quality;
 692          if($this->source_ext == 'pdf') {
 693              $cmd .= ' -define pdf:use-cropbox=true';
 694          }
 695          $cmd .= ' -antialias';
 696          
 697          if($this->sharpen)
 698          {
 699              //Sharpen Level
 700              switch($this->sharpen)
 701              {
 702                  case 1: $cmd .= ' -sharpen 1x10'; break;
 703                  case 2:    $cmd .= ' -sharpen 3x10'; break;
 704                  case 3:    $cmd .= ' -sharpen 5x10'; break;
 705                  case 4:    $cmd .= ' -sharpen 7x10'; break;
 706                  case 5: $cmd .= ' -sharpen 9x10'; break;
 707              }
 708          }
 709  
 710          if ($action == 'crop')
 711          {
 712              $cmd .= ' -crop '.$this->width.'x'.$this->height.'+'.$this->x_axis.'+'.$this->y_axis.' ' . escapeshellarg($this->full_src_path.'[0]') . ' -strip ' . escapeshellarg($this->full_dst_path) . ' 2>&1';
 713          }
 714          elseif($action == 'crop-resize-center')
 715          {
 716              // combined centered crop and resize
 717              $cmd .= ' -resize x'.($this->height*2) . " -resize '" . ($this->width*2) . "x<' -resize 50% -gravity center ";
 718              $cmd .= ' -crop '.$this->width.'x'.$this->height.'+0+0 +repage ' . escapeshellarg($this->full_src_path.'[0]') . ' -strip ' . escapeshellarg($this->full_dst_path) . ' 2>&1';
 719          }
 720          elseif ($action == 'rotate')
 721          {
 722              switch ($this->rotation_angle)
 723              {
 724                  case 'hor'    : $angle = '-flop';
 725                      break;
 726                  case 'vrt'    : $angle = '-flip';
 727                      break;
 728                  default        : $angle = '-rotate '.$this->rotation_angle;
 729                      break;
 730              }
 731  
 732              $cmd .= ' '.$angle.' ' . escapeshellarg($this->full_src_path.'[0]') . ' -strip ' . escapeshellarg($this->full_dst_path) . ' 2>&1';
 733          }
 734          else  // Resize
 735          {
 736              $cmd .= ' -resize '.$this->width.'x'.$this->height.' ' . escapeshellarg($this->full_src_path.'[0]') . ' -strip ' . escapeshellarg($this->full_dst_path) . ' 2>&1';
 737          }
 738  
 739          $retval = 1;
 740          
 741          // debug commands
 742          //write_textfile(PHPWCMS_TEMP.'imagemagick.log', date('Y-m-d H:i:s').' - '.$cmd.LF, 'a');
 743  
 744          @exec($cmd, $output, $retval);
 745  
 746          //    Did it work?
 747          if ($retval > 0)
 748          {
 749              $this->set_error('imglib_image_process_failed');
 750              return FALSE;
 751          }
 752  
 753          // Set the file to 777
 754          @chmod($this->full_dst_path, 0666);
 755  
 756          return TRUE;
 757      }
 758  
 759      // --------------------------------------------------------------------
 760  
 761      /**
 762       * Image Process Using NetPBM
 763       *
 764       * This function will resize, crop or rotate
 765       *
 766       * @param    string
 767       * @return    bool
 768       */
 769  	function image_process_netpbm($action = 'resize')
 770      {
 771          if ($this->library_path == '')
 772          {
 773              $this->set_error('imglib_libpath_invalid');
 774              return FALSE;
 775          }
 776  
 777          //  Build the resizing command
 778          switch ($this->image_type)
 779          {
 780              case 1 :
 781                          $cmd_in        = 'giftopnm';
 782                          $cmd_out    = 'ppmtogif';
 783                  break;
 784              case 2 :
 785                          $cmd_in        = 'jpegtopnm';
 786                          $cmd_out    = 'ppmtojpeg';
 787                  break;
 788              case 3 :
 789                          $cmd_in        = 'pngtopnm';
 790                          $cmd_out    = 'ppmtopng';
 791                  break;
 792          }
 793  
 794          if ($action == 'crop')
 795          {
 796              $cmd_inner = 'pnmcut -left '.$this->x_axis.' -top '.$this->y_axis.' -width '.$this->width.' -height '.$this->height;
 797          }
 798          elseif ($action == 'rotate')
 799          {
 800              switch ($this->rotation_angle)
 801              {
 802                  case 90        :    $angle = 'r270';
 803                      break;
 804                  case 180    :    $angle = 'r180';
 805                      break;
 806                  case 270    :    $angle = 'r90';
 807                      break;
 808                  case 'vrt'    :    $angle = 'tb';
 809                      break;
 810                  case 'hor'    :    $angle = 'lr';
 811                      break;
 812              }
 813  
 814              $cmd_inner = 'pnmflip -'.$angle.' ';
 815          }
 816          else // Resize
 817          {
 818              $cmd_inner = 'pnmscale -xysize '.$this->width.' '.$this->height;
 819          }
 820  
 821          $cmd = $this->library_path.$cmd_in.' '.$this->full_src_path.' | '.$cmd_inner.' | '.$cmd_out.' > '.$this->dest_folder.'netpbm.tmp';
 822  
 823          $retval = 1;
 824  
 825          @exec($cmd, $output, $retval);
 826  
 827          //  Did it work?
 828          if ($retval > 0)
 829          {
 830              $this->set_error('imglib_image_process_failed');
 831              return FALSE;
 832          }
 833  
 834          // With NetPBM we have to create a temporary image.
 835          // If you try manipulating the original it fails so
 836          // we have to rename the temp file.
 837          copy ($this->dest_folder.'netpbm.tmp', $this->full_dst_path);
 838          unlink ($this->dest_folder.'netpbm.tmp');
 839          @chmod($this->full_dst_path, 0666);
 840  
 841          return TRUE;
 842      }
 843  
 844      // --------------------------------------------------------------------
 845  
 846      /**
 847       * Image Rotate Using GD
 848       *
 849       * @return    bool
 850       */
 851  	function image_rotate_gd()
 852      {
 853          //  Create the image handle
 854          if ( ! ($src_img = $this->image_create_gd()))
 855          {
 856              return FALSE;
 857          }
 858  
 859          // Set the background color
 860          // This won't work with transparent PNG files so we are
 861          // going to have to figure out how to determine the color
 862          // of the alpha channel in a future release.
 863  
 864          $white    = imagecolorallocate($src_img, 255, 255, 255);
 865  
 866          //  Rotate it!
 867          $dst_img = imagerotate($src_img, $this->rotation_angle, $white);
 868  
 869          //  Save the Image
 870          if ($this->dynamic_output == TRUE)
 871          {
 872              $this->image_display_gd($dst_img);
 873          }
 874          else
 875          {
 876              // Or save it
 877              if ( ! $this->image_save_gd($dst_img))
 878              {
 879                  return FALSE;
 880              }
 881          }
 882  
 883          //  Kill the file handles
 884          imagedestroy($dst_img);
 885          imagedestroy($src_img);
 886  
 887          // Set the file to 777
 888  
 889          @chmod($this->full_dst_path, 0666);
 890  
 891          return TRUE;
 892      }
 893  
 894      // --------------------------------------------------------------------
 895  
 896      /**
 897       * Create Mirror Image using GD
 898       *
 899       * This function will flip horizontal or vertical
 900       *
 901       * @return    bool
 902       */
 903  	function image_mirror_gd()
 904      {
 905          if ( ! $src_img = $this->image_create_gd())
 906          {
 907              return FALSE;
 908          }
 909  
 910          $width  = $this->orig_width;
 911          $height = $this->orig_height;
 912  
 913          if ($this->rotation_angle == 'hor')
 914          {
 915              for ($i = 0; $i < $height; $i++, $left = 0, $right = $width-1)
 916              {
 917                  while ($left < $right)
 918                  {
 919                      $cl = imagecolorat($src_img, $left, $i);
 920                      $cr = imagecolorat($src_img, $right, $i);
 921  
 922                      imagesetpixel($src_img, $left, $i, $cr);
 923                      imagesetpixel($src_img, $right, $i, $cl);
 924  
 925                      $left++;
 926                      $right--;
 927                  }
 928              }
 929          }
 930          else
 931          {
 932              for ($i = 0; $i < $width; $i++, $top = 0, $bot = $height-1)
 933              {
 934                  while ($top < $bot)
 935                  {
 936                      $ct = imagecolorat($src_img, $i, $top);
 937                      $cb = imagecolorat($src_img, $i, $bot);
 938  
 939                      imagesetpixel($src_img, $i, $top, $cb);
 940                      imagesetpixel($src_img, $i, $bot, $ct);
 941  
 942                      $top++;
 943                      $bot--;
 944                  }
 945              }
 946          }
 947  
 948          //  Show the image
 949          if ($this->dynamic_output == TRUE)
 950          {
 951              $this->image_display_gd($src_img);
 952          }
 953          else
 954          {
 955              // Or save it
 956              if ( ! $this->image_save_gd($src_img))
 957              {
 958                  return FALSE;
 959              }
 960          }
 961  
 962          //  Kill the file handles
 963          imagedestroy($src_img);
 964  
 965          // Set the file to 777
 966          @chmod($this->full_dst_path, 0666);
 967  
 968          return TRUE;
 969      }
 970  
 971      // --------------------------------------------------------------------
 972  
 973      /**
 974       * Image Watermark
 975       *
 976       * This is a wrapper function that chooses the type
 977       * of watermarking based on the specified preference.
 978       *
 979       * @param    string
 980       * @return    bool
 981       */
 982  	function watermark()
 983      {
 984          if ($this->wm_type == 'overlay')
 985          {
 986              return $this->overlay_watermark();
 987          }
 988          else
 989          {
 990              return $this->text_watermark();
 991          }
 992      }
 993  
 994      // --------------------------------------------------------------------
 995  
 996      /**
 997       * Watermark - Graphic Version
 998       *
 999       * @return    bool
1000       */
1001  	function overlay_watermark()
1002      {
1003          if ( ! function_exists('imagecolortransparent'))
1004          {
1005              $this->set_error('imglib_gd_required');
1006              return FALSE;
1007          }
1008  
1009          //  Fetch source image properties
1010          $this->get_image_properties();
1011  
1012          //  Fetch watermark image properties
1013          $props            = $this->get_image_properties($this->wm_overlay_path, TRUE);
1014          $wm_img_type    = $props['image_type'];
1015          $wm_width        = $props['width'];
1016          $wm_height        = $props['height'];
1017  
1018          //  Create two image resources
1019          $wm_img  = $this->image_create_gd($this->wm_overlay_path, $wm_img_type);
1020          $src_img = $this->image_create_gd($this->full_src_path);
1021  
1022          // Reverse the offset if necessary
1023          // When the image is positioned at the bottom
1024          // we don't want the vertical offset to push it
1025          // further down.  We want the reverse, so we'll
1026          // invert the offset.  Same with the horizontal
1027          // offset when the image is at the right
1028  
1029          $this->wm_vrt_alignment = strtoupper(substr($this->wm_vrt_alignment, 0, 1));
1030          $this->wm_hor_alignment = strtoupper(substr($this->wm_hor_alignment, 0, 1));
1031  
1032          if ($this->wm_vrt_alignment == 'B')
1033              $this->wm_vrt_offset = $this->wm_vrt_offset * -1;
1034  
1035          if ($this->wm_hor_alignment == 'R')
1036              $this->wm_hor_offset = $this->wm_hor_offset * -1;
1037  
1038          //  Set the base x and y axis values
1039          $x_axis = $this->wm_hor_offset + $this->wm_padding;
1040          $y_axis = $this->wm_vrt_offset + $this->wm_padding;
1041  
1042          //  Set the vertical position
1043          switch ($this->wm_vrt_alignment)
1044          {
1045              case 'T':
1046                  break;
1047              case 'M':    $y_axis += ($this->orig_height / 2) - ($wm_height / 2);
1048                  break;
1049              case 'B':    $y_axis += $this->orig_height - $wm_height;
1050                  break;
1051          }
1052  
1053          //  Set the horizontal position
1054          switch ($this->wm_hor_alignment)
1055          {
1056              case 'L':
1057                  break;
1058              case 'C':    $x_axis += ($this->orig_width / 2) - ($wm_width / 2);
1059                  break;
1060              case 'R':    $x_axis += $this->orig_width - $wm_width;
1061                  break;
1062          }
1063  
1064          //  Build the finalized image
1065          if ($wm_img_type == 3 AND function_exists('imagealphablending'))
1066          {
1067              @imagealphablending($src_img, TRUE);
1068          }
1069  
1070          // Set RGB values for text and shadow
1071          $rgba = imagecolorat($wm_img, $this->wm_x_transp, $this->wm_y_transp);
1072          $alpha = ($rgba & 0x7F000000) >> 24;
1073  
1074          // make a best guess as to whether we're dealing with an image with alpha transparency or no/binary transparency
1075          if ($alpha > 0)
1076          {
1077              // copy the image directly, the image's alpha transparency being the sole determinant of blending
1078              imagecopy($src_img, $wm_img, $x_axis, $y_axis, 0, 0, $wm_width, $wm_height);
1079          }
1080          else
1081          {
1082              // set our RGB value from above to be transparent and merge the images with the specified opacity
1083              imagecolortransparent($wm_img, imagecolorat($wm_img, $this->wm_x_transp, $this->wm_y_transp));
1084              imagecopymerge($src_img, $wm_img, $x_axis, $y_axis, 0, 0, $wm_width, $wm_height, $this->wm_opacity);
1085          }
1086  
1087          //  Output the image
1088          if ($this->dynamic_output == TRUE)
1089          {
1090              $this->image_display_gd($src_img);
1091          }
1092          elseif ( ! $this->image_save_gd($src_img))
1093          {
1094              return FALSE;
1095          }
1096  
1097          imagedestroy($src_img);
1098          imagedestroy($wm_img);
1099  
1100          return TRUE;
1101      }
1102  
1103      // --------------------------------------------------------------------
1104  
1105      /**
1106       * Watermark - Text Version
1107       *
1108       * @return    bool
1109       */
1110  	function text_watermark()
1111      {
1112          if ( ! ($src_img = $this->image_create_gd()))
1113          {
1114              return FALSE;
1115          }
1116  
1117          if ($this->wm_use_truetype == TRUE AND ! file_exists($this->wm_font_path))
1118          {
1119              $this->set_error('imglib_missing_font');
1120              return FALSE;
1121          }
1122  
1123          //  Fetch source image properties
1124          $this->get_image_properties();
1125  
1126          // Reverse the vertical offset
1127          // When the image is positioned at the bottom
1128          // we don't want the vertical offset to push it
1129          // further down.  We want the reverse, so we'll
1130          // invert the offset.  Note: The horizontal
1131          // offset flips itself automatically
1132  
1133          if ($this->wm_vrt_alignment == 'B')
1134              $this->wm_vrt_offset = $this->wm_vrt_offset * -1;
1135  
1136          if ($this->wm_hor_alignment == 'R')
1137              $this->wm_hor_offset = $this->wm_hor_offset * -1;
1138  
1139          // Set font width and height
1140          // These are calculated differently depending on
1141          // whether we are using the true type font or not
1142          if ($this->wm_use_truetype == TRUE)
1143          {
1144              if ($this->wm_font_size == '')
1145              {
1146                  $this->wm_font_size = 17;
1147              }
1148  
1149              $fontwidth  = $this->wm_font_size-($this->wm_font_size/4);
1150              $fontheight = $this->wm_font_size;
1151              $this->wm_vrt_offset += $this->wm_font_size;
1152          }
1153          else
1154          {
1155              $fontwidth  = imagefontwidth($this->wm_font_size);
1156              $fontheight = imagefontheight($this->wm_font_size);
1157          }
1158  
1159          // Set base X and Y axis values
1160          $x_axis = $this->wm_hor_offset + $this->wm_padding;
1161          $y_axis = $this->wm_vrt_offset + $this->wm_padding;
1162  
1163          // Set verticle alignment
1164          if ($this->wm_use_drop_shadow == FALSE)
1165              $this->wm_shadow_distance = 0;
1166  
1167          $this->wm_vrt_alignment = strtoupper(substr($this->wm_vrt_alignment, 0, 1));
1168          $this->wm_hor_alignment = strtoupper(substr($this->wm_hor_alignment, 0, 1));
1169  
1170          switch ($this->wm_vrt_alignment)
1171          {
1172              case 'T':
1173                  break;
1174              case 'M':    $y_axis += ($this->orig_height/2)+($fontheight/2);
1175                  break;
1176              case 'B':    $y_axis += ($this->orig_height - $fontheight - $this->wm_shadow_distance - ($fontheight/2));
1177                  break;
1178          }
1179  
1180          $x_shad = $x_axis + $this->wm_shadow_distance;
1181          $y_shad = $y_axis + $this->wm_shadow_distance;
1182  
1183          // Set horizontal alignment
1184          switch ($this->wm_hor_alignment)
1185          {
1186              case 'L':
1187                  break;
1188              case 'R':
1189                  if ($this->wm_use_drop_shadow)
1190                  {
1191                      $x_shad += ($this->orig_width - $fontwidth*strlen($this->wm_text));
1192                      $x_axis += ($this->orig_width - $fontwidth*strlen($this->wm_text));
1193                  }
1194                  break;
1195              case 'C':
1196                  if ($this->wm_use_drop_shadow)
1197                  {
1198                      $x_shad += floor(($this->orig_width - $fontwidth*strlen($this->wm_text))/2);
1199                      $x_axis += floor(($this->orig_width - $fontwidth*strlen($this->wm_text))/2);
1200                  }
1201                  break;
1202          }
1203  
1204          if ($this->wm_use_drop_shadow)
1205          {
1206              /* Set RGB values for text and shadow
1207               *
1208               * First character is #, so we don't really need it.
1209               * Get the rest of the string and split it into 2-length
1210               * hex values:
1211               */
1212              $txt_color = str_split(substr($this->wm_font_color, 1, 6), 2);
1213              $txt_color = imagecolorclosest($src_img, hexdec($txt_color[0]), hexdec($txt_color[1]), hexdec($txt_color[2]));
1214              $drp_color = str_split(substr($this->wm_shadow_color, 1, 6), 2);
1215              $drp_color = imagecolorclosest($src_img, hexdec($drp_color[0]), hexdec($drp_color[1]), hexdec($drp_color[2]));
1216  
1217              //  Add the text to the source image
1218              if ($this->wm_use_truetype)
1219              {
1220                  imagettftext($src_img, $this->wm_font_size, 0, $x_shad, $y_shad, $drp_color, $this->wm_font_path, $this->wm_text);
1221                  imagettftext($src_img, $this->wm_font_size, 0, $x_axis, $y_axis, $txt_color, $this->wm_font_path, $this->wm_text);
1222              }
1223              else
1224              {
1225                  imagestring($src_img, $this->wm_font_size, $x_shad, $y_shad, $this->wm_text, $drp_color);
1226                  imagestring($src_img, $this->wm_font_size, $x_axis, $y_axis, $this->wm_text, $txt_color);
1227              }
1228          }
1229  
1230          //  Output the final image
1231          if ($this->dynamic_output == TRUE)
1232          {
1233              $this->image_display_gd($src_img);
1234          }
1235          else
1236          {
1237              $this->image_save_gd($src_img);
1238          }
1239  
1240          imagedestroy($src_img);
1241  
1242          return TRUE;
1243      }
1244  
1245      // --------------------------------------------------------------------
1246  
1247      /**
1248       * Create Image - GD
1249       *
1250       * This simply creates an image resource handle
1251       * based on the type of image being processed
1252       *
1253       * @param    string
1254       * @return    resource
1255       */
1256  	function image_create_gd($path = '', $image_type = '')
1257      {
1258          if ($path == '')
1259              $path = $this->full_src_path;
1260  
1261          if ($image_type == '')
1262              $image_type = $this->image_type;
1263  
1264  
1265          switch ($image_type)
1266          {
1267              case     1 :
1268                          if ( ! function_exists('imagecreatefromgif'))
1269                          {
1270                              $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_gif_not_supported'));
1271                              return FALSE;
1272                          }
1273  
1274                          return imagecreatefromgif($path);
1275                  break;
1276              case 2 :
1277                          if ( ! function_exists('imagecreatefromjpeg'))
1278                          {
1279                              $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_jpg_not_supported'));
1280                              return FALSE;
1281                          }
1282  
1283                          return imagecreatefromjpeg($path);
1284                  break;
1285              case 3 :
1286                          if ( ! function_exists('imagecreatefrompng'))
1287                          {
1288                              $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_png_not_supported'));
1289                              return FALSE;
1290                          }
1291  
1292                          return imagecreatefrompng($path);
1293                  break;
1294  
1295          }
1296  
1297          $this->set_error(array('imglib_unsupported_imagecreate'));
1298          return FALSE;
1299      }
1300  
1301      // --------------------------------------------------------------------
1302  
1303      /**
1304       * Write image file to disk - GD
1305       *
1306       * Takes an image resource as input and writes the file
1307       * to the specified destination
1308       *
1309       * @param    resource
1310       * @return    bool
1311       */
1312  	function image_save_gd($resource)
1313      {
1314          switch ($this->image_type)
1315          {
1316              case 1 :
1317                          if ( ! function_exists('imagegif'))
1318                          {
1319                              $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_gif_not_supported'));
1320                              return FALSE;
1321                          }
1322  
1323                          if ( ! @imagegif($resource, $this->full_dst_path))
1324                          {
1325                              $this->set_error('imglib_save_failed');
1326                              return FALSE;
1327                          }
1328                  break;
1329              case 2    :
1330                          if ( ! function_exists('imagejpeg'))
1331                          {
1332                              $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_jpg_not_supported'));
1333                              return FALSE;
1334                          }
1335  
1336                          if ( ! @imagejpeg($resource, $this->full_dst_path, $this->quality))
1337                          {
1338                              $this->set_error('imglib_save_failed');
1339                              return FALSE;
1340                          }
1341                  break;
1342              case 3    :
1343                          if ( ! function_exists('imagepng'))
1344                          {
1345                              $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_png_not_supported'));
1346                              return FALSE;
1347                          }
1348  
1349                          if ( ! @imagepng($resource, $this->full_dst_path))
1350                          {
1351                              $this->set_error('imglib_save_failed');
1352                              return FALSE;
1353                          }
1354                  break;
1355              default        :
1356                              $this->set_error('imglib_unsupported_imagecreate');
1357                              return FALSE;
1358                  break;
1359          }
1360  
1361          return TRUE;
1362      }
1363  
1364      // --------------------------------------------------------------------
1365  
1366      /**
1367       * Dynamically outputs an image
1368       *
1369       * @param    resource
1370       * @return    void
1371       */
1372  	function image_display_gd($resource)
1373      {
1374          header("Content-Disposition: filename={$this->source_image};");
1375          header("Content-Type: {$this->mime_type}");
1376          header('Content-Transfer-Encoding: binary');
1377          header('Last-Modified: '.gmdate('D, d M Y H:i:s', time()).' GMT');
1378  
1379          switch ($this->image_type)
1380          {
1381              case 1        :    imagegif($resource);
1382                  break;
1383              case 2        :    imagejpeg($resource, '', $this->quality);
1384                  break;
1385              case 3        :    imagepng($resource);
1386                  break;
1387              default        :    echo 'Unable to display the image';
1388                  break;
1389          }
1390      }
1391  
1392      // --------------------------------------------------------------------
1393  
1394      /**
1395       * Re-proportion Image Width/Height
1396       *
1397       * When creating thumbs, the desired width/height
1398       * can end up warping the image due to an incorrect
1399       * ratio between the full-sized image and the thumb.
1400       *
1401       * This function lets us re-proportion the width/height
1402       * if users choose to maintain the aspect ratio when resizing.
1403       *
1404       * @return    void
1405       */
1406  	function image_reproportion()
1407      {
1408          if ( ! is_numeric($this->width) OR ! is_numeric($this->height) OR $this->width == 0 OR $this->height == 0)
1409              return;
1410  
1411          if ( ! is_numeric($this->orig_width) OR ! is_numeric($this->orig_height) OR $this->orig_width == 0 OR $this->orig_height == 0)
1412              return;
1413  
1414          $new_width    = ceil($this->orig_width*$this->height/$this->orig_height);
1415          $new_height    = ceil($this->width*$this->orig_height/$this->orig_width);
1416  
1417          $ratio = (($this->orig_height/$this->orig_width) - ($this->height/$this->width));
1418  
1419          if ($this->master_dim != 'width' AND $this->master_dim != 'height')
1420          {
1421              $this->master_dim = ($ratio < 0) ? 'width' : 'height';
1422          }
1423  
1424          if (($this->width != $new_width) AND ($this->height != $new_height))
1425          {
1426              if ($this->master_dim == 'height')
1427              {
1428                  $this->width = $new_width;
1429              }
1430              else
1431              {
1432                  $this->height = $new_height;
1433              }
1434          }
1435      }
1436  
1437      // --------------------------------------------------------------------
1438  
1439      /**
1440       * Get image properties
1441       *
1442       * A helper function that gets info about the file
1443       *
1444       * @param    string
1445       * @return    mixed
1446       */
1447  	function get_image_properties($path = '', $return = FALSE)
1448      {
1449          // For now we require GD but we should
1450          // find a way to determine this using IM or NetPBM
1451  
1452          if ($path == '')
1453              $path = $this->full_src_path;
1454  
1455          if ( ! file_exists($path))
1456          {
1457              $this->set_error('imglib_invalid_path');
1458              return FALSE;
1459          }
1460          
1461          $cache    = md5($path);
1462          
1463          if (!isset($this->image_cache[$cache]))
1464          {
1465  
1466              $vals    = getimagesize($path);
1467              $types    = array(1 => 'gif', 2 => 'jpeg', 3 => 'png');
1468              $mime    = (isset($types[$vals[2]])) ? 'image/'.$types[$vals[2]] : 'image/jpg';
1469              
1470              $this->image_current_vals = $vals;
1471              
1472              $this->image_cache[$cache] = array(
1473                  'orig_width'    => $vals[0],
1474                  'orig_height'    => $vals[1],
1475                  'image_type'    => $vals[2],
1476                  'size_str'        => $vals[3],
1477                  'mime_type'        => $mime
1478              );
1479              
1480  
1481          }
1482          
1483          if ($return == TRUE)
1484          {
1485              return $this->image_cache[$cache];
1486          }
1487          
1488          $this->orig_width    = $this->image_cache[$cache]['orig_width'];
1489          $this->orig_height    = $this->image_cache[$cache]['orig_height'];
1490          $this->image_type    = $this->image_cache[$cache]['image_type'];
1491          $this->size_str        = $this->image_cache[$cache]['size_str'];
1492          $this->mime_type    = $this->image_cache[$cache]['mime_type'];
1493  
1494          return TRUE;
1495      }
1496  
1497      // --------------------------------------------------------------------
1498  
1499      /**
1500       * Size calculator
1501       *
1502       * This function takes a known width x height and
1503       * recalculates it to a new size.  Only one
1504       * new variable needs to be known
1505       *
1506       *    $props = array(
1507       *                    'width'            => $width,
1508       *                    'height'        => $height,
1509       *                    'new_width'        => 40,
1510       *                    'new_height'    => ''
1511       *                  );
1512       *
1513       * @param    array
1514       * @return    array
1515       */
1516  	function size_calculator($vals)
1517      {
1518          if ( ! is_array($vals))
1519          {
1520              return;
1521          }
1522  
1523          $allowed = array('new_width', 'new_height', 'width', 'height');
1524  
1525          foreach ($allowed as $item)
1526          {
1527              if ( ! isset($vals[$item]) OR $vals[$item] == '')
1528                  $vals[$item] = 0;
1529          }
1530  
1531          if ($vals['width'] == 0 OR $vals['height'] == 0)
1532          {
1533              return $vals;
1534          }
1535  
1536          if ($vals['new_width'] == 0)
1537          {
1538              $vals['new_width'] = ceil($vals['width']*$vals['new_height']/$vals['height']);
1539          }
1540          elseif ($vals['new_height'] == 0)
1541          {
1542              $vals['new_height'] = ceil($vals['new_width']*$vals['height']/$vals['width']);
1543          }
1544  
1545          return $vals;
1546      }
1547  
1548      // --------------------------------------------------------------------
1549  
1550      /**
1551       * Explode source_image
1552       *
1553       * This is a helper function that extracts the extension
1554       * from the source_image.  This function lets us deal with
1555       * source_images with multiple periods, like:  my.cool.jpg
1556       * It returns an associative array with two elements:
1557       * $array['ext']  = '.jpg';
1558       * $array['name'] = 'my.cool';
1559       *
1560       * @param    string
1561       * @param    bool
1562       * @return    array
1563       */
1564  	function explode_name($source_image, $ext_only=FALSE)
1565      {
1566          $ext = strrchr($source_image, '.');
1567          $name = ($ext === FALSE) ? $source_image : substr($source_image, 0, -strlen($ext));
1568  
1569          return $ext_only ? strtolower(trim($ext, '.')) : array('ext' => $ext, 'name' => $name);
1570      }
1571  
1572      // --------------------------------------------------------------------
1573  
1574      /**
1575       * Is GD Installed?
1576       *
1577       * @return    bool
1578       */
1579  	function gd_loaded()
1580      {
1581          if ( ! extension_loaded('gd'))
1582          {
1583              /* As it is stated in the PHP manual, dl() is not always available
1584               * and even if so - it could generate an E_WARNING message on failure
1585               */
1586              return (function_exists('dl') AND @dl('gd.so'));
1587          }
1588  
1589          return TRUE;
1590      }
1591  
1592      // --------------------------------------------------------------------
1593  
1594      /**
1595       * Get GD version
1596       *
1597       * @access    public
1598       * @return    mixed
1599       */
1600  	function gd_version()
1601      {
1602          if (function_exists('gd_info'))
1603          {
1604              $gd_version = @gd_info();
1605              $gd_version = preg_replace("/\D/", "", $gd_version['GD Version']);
1606  
1607              return $gd_version;
1608          }
1609  
1610          return FALSE;
1611      }
1612  
1613      // --------------------------------------------------------------------
1614  
1615      /**
1616       * Set error message
1617       *
1618       * @param    string
1619       * @return    void
1620       */
1621  	function set_error($msg)
1622      {    
1623          if(!$this->lang_localized) {
1624              $local_lang = strtolower( isset($_SESSION["wcs_user_lang"]) ? $_SESSION["wcs_user_lang"] : $GLOBALS['phpwcms']['DOCTYPE_LANG'] );
1625              if($local_lang && is_file(PHPWCMS_ROOT.'/include/inc_lang/image/image.'.$local_lang.'.php')) {
1626                  include(PHPWCMS_ROOT.'/include/inc_lang/image/image.'.$local_lang.'.php');
1627                  $this->lang                = array_merge($this->lang, $ci_lang);
1628                  $this->lang_localized    = TRUE;
1629              }
1630          }
1631      
1632          if (is_array($msg))
1633          {
1634              foreach ($msg as $val)
1635              {
1636                  $msg = ($this->lang[$val] == FALSE) ? $val : $this->lang[$val];
1637                  $this->error_msg[] = $msg;
1638              }
1639          }
1640          else
1641          {
1642              $msg = ($this->lang[$msg] == FALSE) ? $msg : $this->lang[$msg];
1643              $this->error_msg[] = $msg;
1644          }
1645      }
1646  
1647      // --------------------------------------------------------------------
1648  
1649      /**
1650       * Show error messages
1651       *
1652       * @param    string
1653       * @return    string
1654       */
1655  	function display_errors($open = '<p>', $close = '</p>', $wrap_open='', $wrap_close='')
1656      {
1657          return (count($this->error_msg) > 0) ? $wrap_open . $open . implode($close . $open, $this->error_msg) . $close . $wrap_close : '';
1658      }
1659  
1660  }
1661  // END Image_lib Class
1662  
1663  /* End of file Image_lib.php */
1664  /* Location: ./system/libraries/Image_lib.php */


Generated: Sun Jan 29 16:31:14 2012 Cross-referenced by PHPXref 0.7.1