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

Documentation generated on Thu, 05 Nov 2009 00:32:58 -0800 by phpDocumentor 1.4.3