Source for file GdThumb.inc.php

Documentation is available at GdThumb.inc.php

  1. <?php
  2. /**
  3.  * PhpThumb GD Thumb Class Definition File
  4.  * 
  5.  * This file contains the definition for the GdThumb object
  6.  * 
  7.  * PHP Version 5 with GD 2.0+
  8.  * PhpThumb : PHP Thumb Library <http://phpthumb.gxdlabs.com>
  9.  * Copyright (c) 2009, Ian Selby/Gen X Design
  10.  * 
  11.  * Author(s): Ian Selby <ian@gen-x-design.com>
  12.  * 
  13.  * Licensed under the MIT License
  14.  * Redistributions of files must retain the above copyright notice.
  15.  * 
  16.  * @author Ian Selby <ian@gen-x-design.com>
  17.  * @copyright Copyright (c) 2009 Gen X Design
  18.  * @link http://phpthumb.gxdlabs.com
  19.  * @license http://www.opensource.org/licenses/mit-license.php The MIT License
  20.  * @version 3.0
  21.  * @package PhpThumb
  22.  * @filesource
  23.  */
  24.  
  25. /**
  26.  * GdThumb Class Definition
  27.  * 
  28.  * This is the GD Implementation of the PHP Thumb library.
  29.  * 
  30.  * @package PhpThumb
  31.  * @subpackage Core
  32.  */
  33. class GdThumb extends ThumbBase
  34. {
  35.     /**
  36.      * The prior image (before manipulation)
  37.      * 
  38.      * @var resource 
  39.      */
  40.     protected $oldImage;
  41.     /**
  42.      * The working image (used during manipulation)
  43.      * 
  44.      * @var resource 
  45.      */
  46.     protected $workingImage;
  47.     /**
  48.      * The current dimensions of the image
  49.      * 
  50.      * @var array 
  51.      */
  52.     protected $currentDimensions;
  53.     /**
  54.      * The new, calculated dimensions of the image
  55.      * 
  56.      * @var array 
  57.      */
  58.     protected $newDimensions;
  59.     /**
  60.      * The options for this class
  61.      * 
  62.      * This array contains various options that determine the behavior in
  63.      * various functions throughout the class.  Functions note which specific
  64.      * option key / values are used in their documentation
  65.      * 
  66.      * @var array 
  67.      */
  68.     protected $options;
  69.     /**
  70.      * The maximum width an image can be after resizing (in pixels)
  71.      * 
  72.      * @var int 
  73.      */
  74.     protected $maxWidth;
  75.     /**
  76.      * The maximum height an image can be after resizing (in pixels)
  77.      * 
  78.      * @var int 
  79.      */
  80.     protected $maxHeight;
  81.     /**
  82.      * The percentage to resize the image by
  83.      * 
  84.      * @var int 
  85.      */
  86.     protected $percent;
  87.     
  88.     /**
  89.      * Class Constructor
  90.      * 
  91.      * @return GdThumb 
  92.      * @param string $fileName 
  93.      */
  94.     public function __construct ($fileName$options array())
  95.     {
  96.         parent::__construct($fileName);
  97.         
  98.         $this->determineFormat();
  99.         $this->verifyFormatCompatiblity();
  100.         
  101.         switch ($this->format)
  102.         {
  103.             case 'GIF':
  104.                 $this->oldImage = imagecreatefromgif($this->fileName);
  105.                 break;
  106.             case 'JPG':
  107.                 $this->oldImage = imagecreatefromjpeg($this->fileName);
  108.                 break;
  109.             case 'PNG':
  110.                 $this->oldImage = imagecreatefrompng($this->fileName);
  111.                 break;
  112.         }
  113.         
  114.         $size getimagesize($this->fileName);
  115.         $this->currentDimensions = array
  116.         (
  117.             'width'     => $size[0],
  118.             'height'    => $size[1]
  119.         );
  120.         
  121.         $this->setOptions($options);
  122.         
  123.         // TODO: Port gatherImageMeta to a separate function that can be called to extract exif data
  124.     }
  125.     
  126.     /**
  127.      * Class Destructor
  128.      * 
  129.      */
  130.     public function __destruct ()
  131.     {
  132.         if (is_resource($this->oldImage))
  133.         {
  134.             imagedestroy($this->oldImage);
  135.         }
  136.         
  137.         if (is_resource($this->workingImage))
  138.         {
  139.             imagedestroy($this->workingImage);
  140.         }
  141.     }
  142.     
  143.     ##############################
  144.     # ----- API FUNCTIONS ------ #
  145.     ##############################
  146.     
  147.     /**
  148.      * Resizes an image to be no larger than $maxWidth or $maxHeight
  149.      * 
  150.      * If either param is set to zero, then that dimension will not be considered as a part of the resize.
  151.      * Additionally, if $this->options['resizeUp'] is set to true (false by default), then this function will
  152.      * also scale the image up to the maximum dimensions provided.
  153.      * 
  154.      * @param int $maxWidth The maximum width of the image in pixels
  155.      * @param int $maxHeight The maximum height of the image in pixels
  156.      * @return GdThumb 
  157.      */
  158.     public function resize ($maxWidth 0$maxHeight 0)
  159.     {
  160.         // make sure our arguments are valid
  161.         if (!is_numeric($maxWidth))
  162.         {
  163.             throw new InvalidArgumentException('$maxWidth must be numeric');
  164.         }
  165.         
  166.         if (!is_numeric($maxHeight))
  167.         {
  168.             throw new InvalidArgumentException('$maxHeight must be numeric');
  169.         }
  170.         
  171.         // make sure we're not exceeding our image size if we're not supposed to
  172.         if ($this->options['resizeUp'=== false)
  173.         {
  174.             $this->maxHeight    = (intval($maxHeight$this->currentDimensions['height']$this->currentDimensions['height'$maxHeight;
  175.             $this->maxWidth        = (intval($maxWidth$this->currentDimensions['width']$this->currentDimensions['width'$maxWidth;
  176.         }
  177.         else
  178.         {
  179.             $this->maxHeight    = intval($maxHeight);
  180.             $this->maxWidth        = intval($maxWidth);
  181.         }
  182.         
  183.         // get the new dimensions...
  184.         $this->calcImageSize($this->currentDimensions['width']$this->currentDimensions['height']);
  185.         
  186.         // create the working image
  187.         if (function_exists('imagecreatetruecolor'))
  188.         {
  189.             $this->workingImage = imagecreatetruecolor($this->newDimensions['newWidth']$this->newDimensions['newHeight']);
  190.         }
  191.         else
  192.         {
  193.             $this->workingImage = imagecreate($this->newDimensions['newWidth']$this->newDimensions['newHeight']);
  194.         }
  195.         
  196.         $this->preserveAlpha();        
  197.         
  198.         // and create the newly sized image
  199.         imagecopyresampled
  200.         (
  201.             $this->workingImage,
  202.             $this->oldImage,
  203.             0,
  204.             0,
  205.             0,
  206.             0,
  207.             $this->newDimensions['newWidth'],
  208.             $this->newDimensions['newHeight'],
  209.             $this->currentDimensions['width'],
  210.             $this->currentDimensions['height']
  211.         );
  212.  
  213.         // update all the variables and resources to be correct
  214.         $this->oldImage                     = $this->workingImage;
  215.         $this->currentDimensions['width']     $this->newDimensions['newWidth'];
  216.         $this->currentDimensions['height']     $this->newDimensions['newHeight'];
  217.         
  218.         return $this;
  219.     }
  220.     
  221.     /**
  222.      * Adaptively Resizes the Image
  223.      * 
  224.      * This function attempts to get the image to as close to the provided dimensions as possible, and then crops the
  225.      * remaining overflow (from the center) to get the image to be the size specified
  226.      * 
  227.      * @param int $maxWidth 
  228.      * @param int $maxHeight 
  229.      * @return GdThumb 
  230.      */
  231.     public function adaptiveResize ($width$height)
  232.     {
  233.         // make sure our arguments are valid
  234.         if (!is_numeric($width|| $width  == 0)
  235.         {
  236.             throw new InvalidArgumentException('$width must be numeric and greater than zero');
  237.         }
  238.         
  239.         if (!is_numeric($height|| $height == 0)
  240.         {
  241.             throw new InvalidArgumentException('$height must be numeric and greater than zero');
  242.         }
  243.         
  244.         // make sure we're not exceeding our image size if we're not supposed to
  245.         if ($this->options['resizeUp'=== false)
  246.         {
  247.             $this->maxHeight    = (intval($height$this->currentDimensions['height']$this->currentDimensions['height'$height;
  248.             $this->maxWidth        = (intval($width$this->currentDimensions['width']$this->currentDimensions['width'$width;
  249.         }
  250.         else
  251.         {
  252.             $this->maxHeight    = intval($height);
  253.             $this->maxWidth        = intval($width);
  254.         }
  255.         
  256.         $this->calcImageSizeStrict($this->currentDimensions['width']$this->currentDimensions['height']);
  257.         
  258.         // resize the image to be close to our desired dimensions
  259.         $this->resize($this->newDimensions['newWidth']$this->newDimensions['newHeight']);
  260.         
  261.         // reset the max dimensions...
  262.         if ($this->options['resizeUp'=== false)
  263.         {
  264.             $this->maxHeight    = (intval($height$this->currentDimensions['height']$this->currentDimensions['height'$height;
  265.             $this->maxWidth        = (intval($width$this->currentDimensions['width']$this->currentDimensions['width'$width;
  266.         }
  267.         else
  268.         {
  269.             $this->maxHeight    = intval($height);
  270.             $this->maxWidth        = intval($width);
  271.         }
  272.         
  273.         // create the working image
  274.         if (function_exists('imagecreatetruecolor'))
  275.         {
  276.             $this->workingImage = imagecreatetruecolor($this->maxWidth$this->maxHeight);
  277.         }
  278.         else
  279.         {
  280.             $this->workingImage = imagecreate($this->maxWidth$this->maxHeight);
  281.         }
  282.         
  283.         $this->preserveAlpha();
  284.         
  285.         $cropWidth    $this->maxWidth;
  286.         $cropHeight    $this->maxHeight;
  287.         $cropX         0;
  288.         $cropY         0;
  289.         
  290.         // now, figure out how to crop the rest of the image...
  291.         if ($this->currentDimensions['width'$this->maxWidth)
  292.         {
  293.             $cropX intval(($this->currentDimensions['width'$this->maxWidth2);
  294.         }
  295.         elseif ($this->currentDimensions['height'$this->maxHeight)
  296.         {
  297.             $cropY intval(($this->currentDimensions['height'$this->maxHeight2);
  298.         }
  299.         
  300.         imagecopyresampled
  301.         (
  302.             $this->workingImage,
  303.             $this->oldImage,
  304.             0,
  305.             0,
  306.             $cropX,
  307.             $cropY,
  308.             $cropWidth,
  309.             $cropHeight,
  310.             $cropWidth,
  311.             $cropHeight
  312.         );
  313.         
  314.         // update all the variables and resources to be correct
  315.         $this->oldImage                     = $this->workingImage;
  316.         $this->currentDimensions['width']     $this->maxWidth;
  317.         $this->currentDimensions['height']     $this->maxHeight;
  318.         
  319.         return $this;
  320.     }
  321.     
  322.     /**
  323.      * Resizes an image by a given percent uniformly
  324.      * 
  325.      * Percentage should be whole number representation (i.e. 1-100)
  326.      * 
  327.      * @param int $percent 
  328.      * @return GdThumb 
  329.      */
  330.     public function resizePercent ($percent 0)
  331.     {
  332.         if (!is_numeric($percent))
  333.         {
  334.             throw new InvalidArgumentException ('$percent must be numeric');
  335.         }
  336.         
  337.         $this->percent = intval($percent);
  338.         
  339.         $this->calcImageSizePercent($this->currentDimensions['width']$this->currentDimensions['height']);
  340.         
  341.         if (function_exists('imagecreatetruecolor'))
  342.         {
  343.             $this->workingImage = imagecreatetruecolor($this->newDimensions['newWidth']$this->newDimensions['newHeight']);
  344.         }
  345.         else
  346.         {
  347.             $this->workingImage = imagecreate($this->newDimensions['newWidth']$this->newDimensions['newHeight']);
  348.         }
  349.         
  350.         $this->preserveAlpha();
  351.         
  352.         ImageCopyResampled(
  353.             $this->workingImage,
  354.             $this->oldImage,
  355.             0,
  356.             0,
  357.             0,
  358.             0,
  359.             $this->newDimensions['newWidth'],
  360.             $this->newDimensions['newHeight'],
  361.             $this->currentDimensions['width'],
  362.             $this->currentDimensions['height']
  363.         );
  364.  
  365.         $this->oldImage                     = $this->workingImage;
  366.         $this->currentDimensions['width']     $this->newDimensions['newWidth'];
  367.         $this->currentDimensions['height']     $this->newDimensions['newHeight'];
  368.         
  369.         return $this;
  370.     }
  371.     
  372.     /**
  373.      * Crops an image from the center with provided dimensions
  374.      * 
  375.      * If no height is given, the width will be used as a height, thus creating a square crop
  376.      * 
  377.      * @param int $cropWidth 
  378.      * @param int $cropHeight 
  379.      * @return GdThumb 
  380.      */
  381.     public function cropFromCenter ($cropWidth$cropHeight null)
  382.     {
  383.         if (!is_numeric($cropWidth))
  384.         {
  385.             throw new InvalidArgumentException('$cropWidth must be numeric');
  386.         }
  387.         
  388.         if ($cropHeight !== null && !is_numeric($cropHeight))
  389.         {
  390.             throw new InvalidArgumentException('$cropHeight must be numeric');
  391.         }
  392.         
  393.         if ($cropHeight === null)
  394.         {
  395.             $cropHeight $cropWidth;
  396.         }
  397.         
  398.         $cropWidth    ($this->currentDimensions['width'$cropWidth$this->currentDimensions['width'$cropWidth;
  399.         $cropHeight ($this->currentDimensions['height'$cropHeight$this->currentDimensions['height'$cropHeight;
  400.         
  401.         $cropX intval(($this->currentDimensions['width'$cropWidth2);
  402.         $cropY intval(($this->currentDimensions['height'$cropHeight2);
  403.         
  404.         $this->crop($cropX$cropY$cropWidth$cropHeight);
  405.         
  406.         return $this;
  407.     }
  408.     
  409.     /**
  410.      * Vanilla Cropping - Crops from x,y with specified width and height
  411.      * 
  412.      * @param int $startX 
  413.      * @param int $startY 
  414.      * @param int $cropWidth 
  415.      * @param int $cropHeight 
  416.      * @return GdThumb 
  417.      */
  418.     public function crop ($startX$startY$cropWidth$cropHeight)
  419.     {
  420.         // validate input
  421.         if (!is_numeric($startX))
  422.         {
  423.             throw new InvalidArgumentException('$startX must be numeric');
  424.         }
  425.         
  426.         if (!is_numeric($startY))
  427.         {
  428.             throw new InvalidArgumentException('$startY must be numeric');
  429.         }
  430.         
  431.         if (!is_numeric($cropWidth))
  432.         {
  433.             throw new InvalidArgumentException('$cropWidth must be numeric');
  434.         }
  435.         
  436.         if (!is_numeric($cropHeight))
  437.         {
  438.             throw new InvalidArgumentException('$cropHeight must be numeric');
  439.         }
  440.         
  441.         // do some calculations
  442.         $cropWidth    ($this->currentDimensions['width'$cropWidth$this->currentDimensions['width'$cropWidth;
  443.         $cropHeight ($this->currentDimensions['height'$cropHeight$this->currentDimensions['height'$cropHeight;
  444.         
  445.         // ensure everything's in bounds
  446.         if (($startX $cropWidth$this->currentDimensions['width'])
  447.         {
  448.             $startX ($this->currentDimensions['width'$cropWidth);
  449.             
  450.         }
  451.         
  452.         if (($startY $cropHeight$this->currentDimensions['height'])
  453.         {
  454.             $startY ($this->currentDimensions['height'$cropHeight);
  455.         }
  456.         
  457.         if ($startX 0
  458.         {
  459.             $startX 0;
  460.         }
  461.         
  462.         if ($startY 0
  463.         {
  464.             $startY 0;
  465.         }
  466.         
  467.         // create the working image
  468.         if (function_exists('imagecreatetruecolor'))
  469.         {
  470.             $this->workingImage = imagecreatetruecolor($cropWidth$cropHeight);
  471.         }
  472.         else
  473.         {
  474.             $this->workingImage = imagecreate($cropWidth$cropHeight);
  475.         }
  476.         
  477.         $this->preserveAlpha();
  478.         
  479.         imagecopyresampled
  480.         (
  481.             $this->workingImage,
  482.             $this->oldImage,
  483.             0,
  484.             0,
  485.             $startX,
  486.             $startY,
  487.             $cropWidth,
  488.             $cropHeight,
  489.             $cropWidth,
  490.             $cropHeight
  491.         );
  492.         
  493.         $this->oldImage                     = $this->workingImage;
  494.         $this->currentDimensions['width']     $cropWidth;
  495.         $this->currentDimensions['height']     $cropHeight;
  496.         
  497.         return $this;
  498.     }
  499.     
  500.     /**
  501.      * Rotates image either 90 degrees clockwise or counter-clockwise
  502.      * 
  503.      * @param string $direction 
  504.      * @retunrn GdThumb
  505.      */
  506.     public function rotateImage ($direction 'CW'
  507.     {
  508.         if ($direction == 'CW'
  509.         {
  510.             $this->rotateImageNDegrees(90);
  511.         }
  512.         else 
  513.         {
  514.             $this->rotateImageNDegrees(-90);
  515.         }
  516.         
  517.         return $this;
  518.     }
  519.     
  520.     /**
  521.      * Rotates image specified number of degrees
  522.      * 
  523.      * @param int $degrees 
  524.      * @return GdThumb 
  525.      */
  526.     public function rotateImageNDegrees ($degrees)
  527.     {
  528.         if (!is_numeric($degrees))
  529.         {
  530.             throw new InvalidArgumentException('$degrees must be numeric');
  531.         }
  532.         
  533.         if (!function_exists('imagerotate'))
  534.         {
  535.             throw new RuntimeException('Your version of GD does not support image rotation.');
  536.         }
  537.         
  538.         $this->workingImage = imagerotate($this->oldImage$degrees0);
  539.         
  540.         $newWidth                             $this->currentDimensions['height'];
  541.         $newHeight                             $this->currentDimensions['width'];
  542.         $this->oldImage                     = $this->workingImage;
  543.         $this->currentDimensions['width']     $newWidth;
  544.         $this->currentDimensions['height']     $newHeight;
  545.         
  546.         return $this;
  547.     }
  548.     
  549.     /**
  550.      * Shows an image
  551.      * 
  552.      * This function will show the current image by first sending the appropriate header
  553.      * for the format, and then outputting the image data. If headers have already been sent,
  554.      * a runtime exception will be thrown
  555.      * 
  556.      * @return GdThumb 
  557.      */
  558.     public function show (
  559.     {
  560.         if (headers_sent())
  561.         {
  562.             throw new RuntimeException('Cannot show image, headers have already been sent');
  563.         }
  564.         
  565.         switch ($this->format
  566.         {
  567.             case 'GIF':
  568.                 header('Content-type: image/gif');
  569.                 imagegif($this->oldImage);
  570.                 break;
  571.             case 'JPG':
  572.                 header('Content-type: image/jpeg');
  573.                 imagejpeg($this->oldImagenull$this->options['jpegQuality']);
  574.                 break;
  575.             case 'PNG':
  576.                 header('Content-type: image/png');
  577.                 imagepng($this->oldImage);
  578.                 break;
  579.         }
  580.         
  581.         return $this;
  582.     }
  583.     
  584.     /**
  585.      * Saves an image
  586.      * 
  587.      * This function will make sure the target directory is writeable, and then save the image.
  588.      * 
  589.      * If the target directory is not writeable, the function will try to correct the permissions (if allowed, this
  590.      * is set as an option ($this->options['correctPermissions']).  If the target cannot be made writeable, then a
  591.      * RuntimeException is thrown.
  592.      * 
  593.      * TODO: Create additional paramter for color matte when saving images with alpha to non-alpha formats (i.e. PNG => JPG)
  594.      * 
  595.      * @param string $fileName The full path and filename of the image to save
  596.      * @param string $format The format to save the image in (optional, must be one of [GIF,JPG,PNG]
  597.      * @return GdThumb 
  598.      */
  599.     public function save ($fileName$format null)
  600.     {
  601.         $validFormats array('GIF''JPG''PNG');
  602.         $format ($format !== nullstrtoupper($format$this->format;
  603.         
  604.         if (!in_array($format$validFormats))
  605.         {
  606.             throw new InvalidArgumentException ('Invalid format type specified in save function: ' $format);
  607.         }
  608.         
  609.         // make sure the directory is writeable
  610.         if (!is_writeable(dirname($fileName)))
  611.         {
  612.             // try to correct the permissions
  613.             if ($this->options['correctPermissions'=== true)
  614.             {
  615.                 @chmod(dirname($fileName)0777);
  616.                 
  617.                 // throw an exception if not writeable
  618.                 if (!is_writeable(dirname($fileName)))
  619.                 {
  620.                     throw new RuntimeException ('File is not writeable, and could not correct permissions: ' $fileName);
  621.                 }
  622.             }
  623.             // throw an exception if not writeable
  624.             else
  625.             {
  626.                 throw new RuntimeException ('File not writeable: ' $fileName);
  627.             }
  628.         }
  629.         
  630.         switch ($format
  631.         {
  632.             case 'GIF':
  633.                 imagegif($this->oldImage$fileName);
  634.                 break;
  635.             case 'JPG':
  636.                 imagejpeg($this->oldImage$fileName$this->options['jpegQuality']);
  637.                 break;
  638.             case 'PNG':
  639.                 imagepng($this->oldImage$fileName);
  640.                 break;
  641.         }
  642.         
  643.         return $this;
  644.     }
  645.     
  646.     #################################
  647.     # ----- GETTERS / SETTERS ----- #
  648.     #################################
  649.     
  650.     /**
  651.      * Sets $this->options to $options
  652.      * 
  653.      * @param array $options 
  654.      */
  655.     public function setOptions ($options array())
  656.     {
  657.         // make sure we've got an array for $this->options (could be null)
  658.         if (!is_array($this->options))
  659.         {
  660.             $this->options = array();
  661.         }
  662.         
  663.         // make sure we've gotten a proper argument
  664.         if (!is_array($options))
  665.         {
  666.             throw new InvalidArgumentException ('setOptions requires an array');
  667.         }
  668.         
  669.         // we've yet to init the default options, so create them here
  670.         if (sizeof($this->options== 0)
  671.         {
  672.             $defaultOptions array 
  673.             (
  674.                 'resizeUp'                => false,
  675.                 'jpegQuality'            => 100,
  676.                 'correctPermissions'    => false,
  677.                 'preserveAlpha'            => true,
  678.                 'alphaMaskColor'        => array (255255255),
  679.                 'preserveTransparency'    => true,
  680.                 'transparencyMaskColor'    => array (000)
  681.             );
  682.         }
  683.         // otherwise, let's use what we've got already
  684.         else
  685.         {
  686.             $defaultOptions $this->options;
  687.         }
  688.         
  689.         $this->options = array_merge($defaultOptions$options);
  690.     }
  691.     
  692.     /**
  693.      * Returns $currentDimensions.
  694.      *
  695.      * @see GdThumb::$currentDimensions
  696.      */
  697.     public function getCurrentDimensions ()
  698.     {
  699.         return $this->currentDimensions;
  700.     }
  701.     
  702.     /**
  703.      * Sets $currentDimensions.
  704.      *
  705.      * @param object $currentDimensions 
  706.      * @see GdThumb::$currentDimensions
  707.      */
  708.     public function setCurrentDimensions ($currentDimensions)
  709.     {
  710.         $this->currentDimensions = $currentDimensions;
  711.     }
  712.     
  713.     /**
  714.      * Returns $maxHeight.
  715.      *
  716.      * @see GdThumb::$maxHeight
  717.      */
  718.     public function getMaxHeight ()
  719.     {
  720.         return $this->maxHeight;
  721.     }
  722.     
  723.     /**
  724.      * Sets $maxHeight.
  725.      *
  726.      * @param object $maxHeight 
  727.      * @see GdThumb::$maxHeight
  728.      */
  729.     public function setMaxHeight ($maxHeight)
  730.     {
  731.         $this->maxHeight = $maxHeight;
  732.     }
  733.     
  734.     /**
  735.      * Returns $maxWidth.
  736.      *
  737.      * @see GdThumb::$maxWidth
  738.      */
  739.     public function getMaxWidth ()
  740.     {
  741.         return $this->maxWidth;
  742.     }
  743.     
  744.     /**
  745.      * Sets $maxWidth.
  746.      *
  747.      * @param object $maxWidth 
  748.      * @see GdThumb::$maxWidth
  749.      */
  750.     public function setMaxWidth ($maxWidth)
  751.     {
  752.         $this->maxWidth = $maxWidth;
  753.     }
  754.     
  755.     /**
  756.      * Returns $newDimensions.
  757.      *
  758.      * @see GdThumb::$newDimensions
  759.      */
  760.     public function getNewDimensions ()
  761.     {
  762.         return $this->newDimensions;
  763.     }
  764.     
  765.     /**
  766.      * Sets $newDimensions.
  767.      *
  768.      * @param object $newDimensions 
  769.      * @see GdThumb::$newDimensions
  770.      */
  771.     public function setNewDimensions ($newDimensions)
  772.     {
  773.         $this->newDimensions = $newDimensions;
  774.     }
  775.     
  776.     /**
  777.      * Returns $options.
  778.      *
  779.      * @see GdThumb::$options
  780.      */
  781.     public function getOptions ()
  782.     {
  783.         return $this->options;
  784.     }
  785.     
  786.     /**
  787.      * Returns $percent.
  788.      *
  789.      * @see GdThumb::$percent
  790.      */
  791.     public function getPercent ()
  792.     {
  793.         return $this->percent;
  794.     }
  795.     
  796.     /**
  797.      * Sets $percent.
  798.      *
  799.      * @param object $percent 
  800.      * @see GdThumb::$percent
  801.      */
  802.     public function setPercent ($percent)
  803.     {
  804.         $this->percent = $percent;
  805.     
  806.     
  807.     /**
  808.      * Returns $oldImage.
  809.      *
  810.      * @see GdThumb::$oldImage
  811.      */
  812.     public function getOldImage ()
  813.     {
  814.         return $this->oldImage;
  815.     }
  816.     
  817.     /**
  818.      * Sets $oldImage.
  819.      *
  820.      * @param object $oldImage 
  821.      * @see GdThumb::$oldImage
  822.      */
  823.     public function setOldImage ($oldImage)
  824.     {
  825.         $this->oldImage = $oldImage;
  826.     }
  827.     
  828.     /**
  829.      * Returns $workingImage.
  830.      *
  831.      * @see GdThumb::$workingImage
  832.      */
  833.     public function getWorkingImage ()
  834.     {
  835.         return $this->workingImage;
  836.     }
  837.     
  838.     /**
  839.      * Sets $workingImage.
  840.      *
  841.      * @param object $workingImage 
  842.      * @see GdThumb::$workingImage
  843.      */
  844.     public function setWorkingImage ($workingImage)
  845.     {
  846.         $this->workingImage = $workingImage;
  847.     
  848.     
  849.     
  850.     #################################
  851.     # ----- UTILITY FUNCTIONS ----- #
  852.     #################################
  853.     
  854.     /**
  855.      * Calculates a new width and height for the image based on $this->maxWidth and the provided dimensions
  856.      * 
  857.      * @return array 
  858.      * @param int $width 
  859.      * @param int $height 
  860.      */
  861.     protected function calcWidth ($width$height)
  862.     {
  863.         $newWidthPercentage    (100 $this->maxWidth$width;
  864.         $newHeight            ($height $newWidthPercentage100;
  865.         
  866.         return array
  867.         (
  868.             'newWidth'    => intval($this->maxWidth),
  869.             'newHeight'    => intval($newHeight)
  870.         );
  871.     }
  872.     
  873.     /**
  874.      * Calculates a new width and height for the image based on $this->maxWidth and the provided dimensions
  875.      * 
  876.      * @return array 
  877.      * @param int $width 
  878.      * @param int $height 
  879.      */
  880.     protected function calcHeight ($width$height)
  881.     {
  882.         $newHeightPercentage    (100 $this->maxHeight$height;
  883.         $newWidth                 ($width $newHeightPercentage100;
  884.         
  885.         return array
  886.         (
  887.             'newWidth'    => ceil($newWidth),
  888.             'newHeight'    => ceil($this->maxHeight)
  889.         );
  890.     }
  891.     
  892.     /**
  893.      * Calculates a new width and height for the image based on $this->percent and the provided dimensions
  894.      * 
  895.      * @return array 
  896.      * @param int $width 
  897.      * @param int $height 
  898.      */
  899.     protected function calcPercent ($width$height)
  900.     {
  901.         $newWidth    ($width $this->percent100;
  902.         $newHeight    ($height $this->percent100;
  903.         
  904.         return array 
  905.         (
  906.             'newWidth'    => ceil($newWidth),
  907.             'newHeight'    => ceil($newHeight)
  908.         );
  909.     }
  910.     
  911.     /**
  912.      * Calculates the new image dimensions
  913.      * 
  914.      * These calculations are based on both the provided dimensions and $this->maxWidth and $this->maxHeight
  915.      * 
  916.      * @param int $width 
  917.      * @param int $height 
  918.      */
  919.     protected function calcImageSize ($width$height)
  920.     {
  921.         $newSize array
  922.         (
  923.             'newWidth'    => $width,
  924.             'newHeight'    => $height
  925.         );
  926.         
  927.         if ($this->maxWidth > 0)
  928.         {
  929.             $newSize $this->calcWidth($width$height);
  930.             
  931.             if ($this->maxHeight > && $newSize['newHeight'$this->maxHeight)
  932.             {
  933.                 $newSize $this->calcHeight($newSize['newWidth']$newSize['newHeight']);
  934.             }
  935.         }
  936.         
  937.         if ($this->maxHeight > 0)
  938.         {
  939.             $newSize $this->calcHeight($width$height);
  940.             
  941.             if ($this->maxWidth > && $newSize['newWidth'$this->maxWidth)
  942.             {
  943.                 $newSize $this->calcWidth($newSize['newWidth']$newSize['newHeight']);
  944.             }
  945.         }
  946.         
  947.         $this->newDimensions = $newSize;
  948.     }
  949.     
  950.     /**
  951.      * Calculates new image dimensions, not allowing the width and height to be less than either the max width or height
  952.      * 
  953.      * @param int $width 
  954.      * @param int $height 
  955.      */
  956.     protected function calcImageSizeStrict ($width$height)
  957.     {
  958.         // first, we need to determine what the longest resize dimension is..
  959.         if ($this->maxWidth >= $this->maxHeight)
  960.         {
  961.             // and determine the longest original dimension
  962.             if ($width $height)
  963.             {
  964.                 $newDimensions $this->calcHeight($width$height);
  965.                 
  966.                 if ($newDimensions['newWidth'$this->maxWidth)
  967.                 {
  968.                     $newDimensions $this->calcWidth($width$height);
  969.                 }
  970.             }
  971.             elseif ($height >= $width)
  972.             {
  973.                 $newDimensions $this->calcWidth($width$height);
  974.                 
  975.                 if ($newDimensions['newHeight'$this->maxHeight)
  976.                 {
  977.                     $newDimensions $this->calcHeight($width$height);
  978.                 }
  979.             }
  980.         }
  981.         elseif ($this->maxHeight > $this->maxWidth)
  982.         {
  983.             if ($width >= $height)
  984.             {
  985.                 $newDimensions $this->calcWidth($width$height);
  986.                 
  987.                 if ($newDimensions['newHeight'$this->maxHeight)
  988.                 {
  989.                     $newDimensions $this->calcHeight($width$height);
  990.                 }
  991.             }
  992.             elseif ($height $width)
  993.             {
  994.                 $newDimensions $this->calcHeight($width$height);
  995.                 
  996.                 if ($newDimensions['newWidth'$this->maxWidth)
  997.                 {
  998.                     $newDimensions $this->calcWidth($width$height);
  999.                 }
  1000.             }
  1001.         }
  1002.         
  1003.         $this->newDimensions = $newDimensions;
  1004.     }
  1005.     
  1006.     /**
  1007.      * Calculates new dimensions based on $this->percent and the provided dimensions
  1008.      * 
  1009.      * @param int $width 
  1010.      * @param int $height 
  1011.      */
  1012.     protected function calcImageSizePercent ($width$height)
  1013.     {
  1014.         if ($this->percent > 0)
  1015.         {
  1016.             $this->newDimensions = $this->calcPercent($width$height);
  1017.         }
  1018.     }
  1019.     
  1020.     /**
  1021.      * Determines the file format by mime-type
  1022.      * 
  1023.      * This function will throw exceptions for invalid images / mime-types
  1024.      * 
  1025.      */
  1026.     protected function determineFormat ()
  1027.     {
  1028.         $formatInfo getimagesize($this->fileName);
  1029.         
  1030.         // non-image files will return false
  1031.         if ($formatInfo === false)
  1032.         {
  1033.             if ($this->remoteImage)
  1034.             {
  1035.                 $this->triggerError('Could not determine format of remote image: ' $this->fileName);
  1036.             }
  1037.             else
  1038.             {
  1039.                 $this->triggerError('File is not a valid image: ' $this->fileName);
  1040.             }
  1041.             
  1042.             // make sure we really stop execution
  1043.             return;
  1044.         }
  1045.         
  1046.         $mimeType = isset($formatInfo['mime']$formatInfo['mime'null;
  1047.         
  1048.         switch ($mimeType)
  1049.         {
  1050.             case 'image/gif':
  1051.                 $this->format = 'GIF';
  1052.                 break;
  1053.             case 'image/jpeg':
  1054.                 $this->format = 'JPG';
  1055.                 break;
  1056.             case 'image/png':
  1057.                 $this->format = 'PNG';
  1058.                 break;
  1059.             default:
  1060.                 $this->triggerError('Image format not supported: ' $mimeType);
  1061.         }
  1062.     }
  1063.     
  1064.     /**
  1065.      * Makes sure the correct GD implementation exists for the file type
  1066.      * 
  1067.      */
  1068.     protected function verifyFormatCompatiblity ()
  1069.     {
  1070.         $isCompatible     true;
  1071.         $gdInfo            gd_info();
  1072.         
  1073.         switch ($this->format)
  1074.         {
  1075.             case 'GIF':
  1076.                 $isCompatible $gdInfo['GIF Create Support'];
  1077.                 break;
  1078.             case 'JPG':
  1079.             case 'PNG':
  1080.                 $isCompatible $gdInfo[$this->format . ' Support'];
  1081.                 break;
  1082.             default:
  1083.                 $isCompatible false;
  1084.         }
  1085.         
  1086.         if (!$isCompatible)
  1087.         {
  1088.             // one last check for "JPEG" instead
  1089.             $isCompatible $gdInfo['JPEG Support'];
  1090.             
  1091.             if (!$isCompatible)
  1092.             {
  1093.                 $this->triggerError('Your GD installation does not support ' $this->format . ' image types');
  1094.             }
  1095.         }
  1096.     }
  1097.     
  1098.     /**
  1099.      * Preserves the alpha or transparency for PNG and GIF files
  1100.      * 
  1101.      * Alpha / transparency will not be preserved if the appropriate options are set to false.
  1102.      * Also, the GIF transparency is pretty skunky (the results aren't awesome), but it works like a
  1103.      * champ... that's the nature of GIFs tho, so no huge surprise.
  1104.      * 
  1105.      * This functionality was originally suggested by commenter Aimi (no links / site provided) - Thanks! :)
  1106.      *   
  1107.      */
  1108.     protected function preserveAlpha ()
  1109.     {
  1110.         if ($this->format == 'PNG' && $this->options['preserveAlpha'=== true)
  1111.         {
  1112.             imagealphablending($this->workingImagefalse);
  1113.             
  1114.             $colorTransparent imagecolorallocatealpha
  1115.             (
  1116.                 $this->workingImage
  1117.                 $this->options['alphaMaskColor'][0]
  1118.                 $this->options['alphaMaskColor'][1]
  1119.                 $this->options['alphaMaskColor'][2]
  1120.                 0
  1121.             );
  1122.             
  1123.             imagefill($this->workingImage00$colorTransparent);
  1124.             imagesavealpha($this->workingImagetrue);
  1125.         }
  1126.         // preserve transparency in GIFs... this is usually pretty rough tho
  1127.         if ($this->format == 'GIF' && $this->options['preserveTransparency'=== true)
  1128.         {
  1129.             $colorTransparent imagecolorallocate
  1130.             (
  1131.                 $this->workingImage
  1132.                 $this->options['transparencyMaskColor'][0]
  1133.                 $this->options['transparencyMaskColor'][1]
  1134.                 $this->options['transparencyMaskColor'][2
  1135.             );
  1136.             
  1137.             imagecolortransparent($this->workingImage$colorTransparent);
  1138.             imagetruecolortopalette($this->workingImagetrue256);
  1139.         }
  1140.     }
  1141. }

Documentation generated on Tue, 09 Aug 2011 09:04:57 +0200 by phpDocumentor 1.4.3