diff options
Diffstat (limited to 'system/libraries/drivers/Image')
-rw-r--r-- | system/libraries/drivers/Image/GD.php | 69 | ||||
-rw-r--r-- | system/libraries/drivers/Image/GraphicsMagick.php | 14 | ||||
-rw-r--r-- | system/libraries/drivers/Image/ImageMagick.php | 39 |
3 files changed, 88 insertions, 34 deletions
diff --git a/system/libraries/drivers/Image/GD.php b/system/libraries/drivers/Image/GD.php index be2af4e2..6ffffe8a 100644 --- a/system/libraries/drivers/Image/GD.php +++ b/system/libraries/drivers/Image/GD.php @@ -2,12 +2,12 @@ /** * GD Image Driver. * - * $Id: GD.php 3769 2008-12-15 00:48:56Z zombor $ + * $Id: GD.php 4679 2009-11-10 01:45:52Z isaiah $ * * @package Image * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html + * @copyright (c) 2007-2009 Kohana Team + * @license http://kohanaphp.com/license */ class Image_GD_Driver extends Image_Driver { @@ -20,17 +20,17 @@ class Image_GD_Driver extends Image_Driver { { // Make sure that GD2 is available if ( ! function_exists('gd_info')) - throw new Kohana_Exception('image.gd.requires_v2'); + throw new Kohana_Exception('The Image library requires GD2. Please see http://php.net/gd_info for more information.'); // Get the GD information $info = gd_info(); // Make sure that the GD2 is installed if (strpos($info['GD Version'], '2.') === FALSE) - throw new Kohana_Exception('image.gd.requires_v2'); + throw new Kohana_Exception('The Image library requires GD2. Please see http://php.net/gd_info for more information.'); } - public function process($image, $actions, $dir, $file, $render = FALSE) + public function process($image, $actions, $dir, $file, $render = FALSE, $background = NULL) { // Set the "create" function switch ($image['type']) @@ -63,11 +63,11 @@ class Image_GD_Driver extends Image_Driver { // Make sure the image type is supported for import if (empty($create) OR ! function_exists($create)) - throw new Kohana_Exception('image.type_not_allowed', $image['file']); + throw new Kohana_Exception('The specified image, :type:, is not an allowed image type.', array(':type:' => $image['file'])); // Make sure the image type is supported for saving if (empty($save) OR ! function_exists($save)) - throw new Kohana_Exception('image.type_not_allowed', $dir.$file); + throw new Kohana_Exception('The specified image, :type:, is not an allowed image type.', array(':type:' => $dir.$file)); // Load the image $this->image = $image; @@ -211,11 +211,11 @@ class Image_GD_Driver extends Image_Driver { // Recalculate the percentage to a pixel size $properties['height'] = round($height * (substr($properties['height'], 0, -1) / 100)); } - + // Recalculate the width and height, if they are missing empty($properties['width']) and $properties['width'] = round($width * $properties['height'] / $height); empty($properties['height']) and $properties['height'] = round($height * $properties['width'] / $width); - + if ($properties['master'] === Image::AUTO) { // Change an automatic master dim to the correct type @@ -314,7 +314,7 @@ class Image_GD_Driver extends Image_Driver { { // Make sure that the sharpening function is available if ( ! function_exists('imageconvolution')) - throw new Kohana_Exception('image.unsupported_method', __FUNCTION__); + throw new Kohana_Exception('Your configured driver does not support the :method: image transformation.', array(':method:' => __FUNCTION__)); // Amount should be in the range of 18-10 $amount = round(abs(-18 + ($amount * 0.08)), 2); @@ -336,23 +336,52 @@ class Image_GD_Driver extends Image_Driver { switch($properties['mime']) { case "image/jpeg": - $overlay_img = imagecreatefromjpeg($properties['overlay_file']); + $overlay_img = imagecreatefromjpeg($properties['overlay_file']); break; case "image/gif": - $overlay_img = imagecreatefromgif($properties['overlay_file']); + $overlay_img = imagecreatefromgif($properties['overlay_file']); break; case "image/png": - $overlay_img = imagecreatefrompng($properties['overlay_file']); + $overlay_img = imagecreatefrompng($properties['overlay_file']); break; } - imagecopymerge($this->tmp_image, $overlay_img, $properties['x'], $properties['y'], 0, 0, imagesx($overlay_img), imagesy($overlay_img), $properties['transparency']); + $this->imagecopymerge_alpha($this->tmp_image, $overlay_img, $properties['x'], $properties['y'], 0, 0, imagesx($overlay_img), imagesy($overlay_img), $properties['transparency']); + imagedestroy($overlay_img); + return TRUE; } + /** + * A replacement for php's imagecopymerge() function that supports the alpha channel + * See php bug #23815: http://bugs.php.net/bug.php?id=23815 + * + * @param resource $dst_im Destination image link resource + * @param resource $src_im Source image link resource + * @param integer $dst_x x-coordinate of destination point + * @param integer $dst_y y-coordinate of destination point + * @param integer $src_x x-coordinate of source point + * @param integer $src_y y-coordinate of source point + * @param integer $src_w Source width + * @param integer $src_h Source height + * @param integer $pct Transparency percent (0 to 100) + */ + protected function imagecopymerge_alpha($dst_im, $src_im, $dst_x, $dst_y, $src_x, $src_y, $src_w, $src_h, $pct) + { + // Create a new blank image the site of our source image + $cut = imagecreatetruecolor($src_w, $src_h); + + // Copy the blank image into the destination image where the source goes + imagecopy($cut, $dst_im, 0, 0, $dst_x, $dst_y, $src_w, $src_h); + + // Place the source image in the destination image + imagecopy($cut, $src_im, 0, 0, $src_x, $src_y, $src_w, $src_h); + imagecopymerge($dst_im, $cut, $dst_x, $dst_y, $src_x, $src_y, $src_w, $src_h, $pct); + } + protected function properties() { return array(imagesx($this->tmp_image), imagesy($this->tmp_image)); @@ -368,6 +397,16 @@ class Image_GD_Driver extends Image_Driver { */ protected function imagecreatetransparent($width, $height) { + if ($width < 1) + { + $width = 1; + } + + if ($height < 1) + { + $height = 1; + } + if (self::$blank_png === NULL) { // Decode the blank PNG if it has not been done already diff --git a/system/libraries/drivers/Image/GraphicsMagick.php b/system/libraries/drivers/Image/GraphicsMagick.php index a8bc4d9b..89b40b41 100644 --- a/system/libraries/drivers/Image/GraphicsMagick.php +++ b/system/libraries/drivers/Image/GraphicsMagick.php @@ -4,8 +4,8 @@ * * @package Image * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html + * @copyright (c) 2007-2009 Kohana Team + * @license http://kohanaphp.com/license */ class Image_GraphicsMagick_Driver extends Image_Driver { @@ -31,7 +31,7 @@ class Image_GraphicsMagick_Driver extends Image_Driver { { // Attempt to locate GM by using "which" (only works for *nix!) if ( ! is_file($path = exec('which gm'))) - throw new Kohana_Exception('image.graphicsmagick.not_found'); + throw new Kohana_Exception('The GraphicsMagick directory specified does not contain a required program.'); $config['directory'] = dirname($path); } @@ -41,7 +41,7 @@ class Image_GraphicsMagick_Driver extends Image_Driver { // Check to make sure the provided path is correct if ( ! is_file(realpath($config['directory']).'/gm'.$this->ext)) - throw new Kohana_Exception('image.graphicsmagick.not_found', 'gm'.$this->ext); + throw new Kohana_Exception('The GraphicsMagick directory specified does not contain a required program, :gm:.', array(':gm:' => 'gm'.$this->ext)); // Set the installation directory @@ -52,8 +52,12 @@ class Image_GraphicsMagick_Driver extends Image_Driver { * Creates a temporary image and executes the given actions. By creating a * temporary copy of the image before manipulating it, this process is atomic. */ - public function process($image, $actions, $dir, $file, $render = FALSE) + public function process($image, $actions, $dir, $file, $render = FALSE, $background = NULL) { + // Need to implement $background support + if ($background !== NULL) + throw new Kohana_Exception('The GraphicsMagick driver does not support setting a background color'); + // We only need the filename $image = $image['file']; diff --git a/system/libraries/drivers/Image/ImageMagick.php b/system/libraries/drivers/Image/ImageMagick.php index 4b381fd6..31862f75 100644 --- a/system/libraries/drivers/Image/ImageMagick.php +++ b/system/libraries/drivers/Image/ImageMagick.php @@ -2,12 +2,12 @@ /** * ImageMagick Image Driver. * - * $Id: ImageMagick.php 3769 2008-12-15 00:48:56Z zombor $ + * $Id: ImageMagick.php 4679 2009-11-10 01:45:52Z isaiah $ * * @package Image * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html + * @copyright (c) 2007-2009 Kohana Team + * @license http://kohanaphp.com/license */ class Image_ImageMagick_Driver extends Image_Driver { @@ -33,7 +33,7 @@ class Image_ImageMagick_Driver extends Image_Driver { { // Attempt to locate IM by using "which" (only works for *nix!) if ( ! is_file($path = exec('which convert'))) - throw new Kohana_Exception('image.imagemagick.not_found'); + throw new Kohana_Exception('The ImageMagick directory specified does not contain a required program.'); $config['directory'] = dirname($path); } @@ -43,7 +43,7 @@ class Image_ImageMagick_Driver extends Image_Driver { // Check to make sure the provided path is correct if ( ! is_file(realpath($config['directory']).'/convert'.$this->ext)) - throw new Kohana_Exception('image.imagemagick.not_found', 'convert'.$this->ext); + throw new Kohana_Exception('The ImageMagick directory specified does not contain a required program, :im:', array(':im:' => 'convert'.$this->ext)); // Set the installation directory $this->dir = str_replace('\\', '/', realpath($config['directory'])).'/'; @@ -53,7 +53,7 @@ class Image_ImageMagick_Driver extends Image_Driver { * Creates a temporary image and executes the given actions. By creating a * temporary copy of the image before manipulating it, this process is atomic. */ - public function process($image, $actions, $dir, $file, $render = FALSE) + public function process($image, $actions, $dir, $file, $render = FALSE, $background = NULL) { // We only need the filename $image = $image['file']; @@ -70,23 +70,34 @@ class Image_ImageMagick_Driver extends Image_Driver { // Use 95 for the default quality empty($quality) and $quality = 95; + if (is_string($background)) + { + // Set the background color + $this->background = escapeshellarg($background); + } + else + { + // Use a transparent background + $this->background = 'transparent'; + } + // All calls to these will need to be escaped, so do it now $this->cmd_image = escapeshellarg($this->tmp_image); - $this->new_image = ($render)? $this->cmd_image : escapeshellarg($dir.$file); + $this->new_image = $render ? $this->cmd_image : escapeshellarg($dir.$file); if ($status = $this->execute($actions)) { // Use convert to change the image into its final version. This is // done to allow the file type to change correctly, and to handle // the quality conversion in the most effective way possible. - if ($error = exec(escapeshellcmd($this->dir.'convert'.$this->ext).' -quality '.$quality.'% '.$this->cmd_image.' '.$this->new_image)) + if ($error = exec(escapeshellcmd($this->dir.'convert'.$this->ext).' -background '.$this->background.' -flatten -quality '.$quality.'% '.$this->cmd_image.' '.$this->new_image)) { $this->errors[] = $error; } else { // Output the image directly to the browser - if ($render !== FALSE) + if ($render === TRUE) { $contents = file_get_contents($this->tmp_image); switch (substr($file, strrpos($file, '.') + 1)) @@ -122,7 +133,7 @@ class Image_ImageMagick_Driver extends Image_Driver { // Set the IM geometry based on the properties $geometry = escapeshellarg($prop['width'].'x'.$prop['height'].'+'.$prop['left'].'+'.$prop['top']); - if ($error = exec(escapeshellcmd($this->dir.'convert'.$this->ext).' -crop '.$geometry.' '.$this->cmd_image.' '.$this->cmd_image)) + if ($error = exec(escapeshellcmd($this->dir.'convert'.$this->ext).' -background '.$this->background.' -flatten -crop '.$geometry.' '.$this->cmd_image.' '.$this->cmd_image)) { $this->errors[] = $error; return FALSE; @@ -136,7 +147,7 @@ class Image_ImageMagick_Driver extends Image_Driver { // Convert the direction into a IM command $dir = ($dir === Image::HORIZONTAL) ? '-flop' : '-flip'; - if ($error = exec(escapeshellcmd($this->dir.'convert'.$this->ext).' '.$dir.' '.$this->cmd_image.' '.$this->cmd_image)) + if ($error = exec(escapeshellcmd($this->dir.'convert'.$this->ext).' -background '.$this->background.' -flatten '.$dir.' '.$this->cmd_image.' '.$this->cmd_image)) { $this->errors[] = $error; return FALSE; @@ -164,7 +175,7 @@ class Image_ImageMagick_Driver extends Image_Driver { } // Use "convert" to change the width and height - if ($error = exec(escapeshellcmd($this->dir.'convert'.$this->ext).' -resize '.$dim.' '.$this->cmd_image.' '.$this->cmd_image)) + if ($error = exec(escapeshellcmd($this->dir.'convert'.$this->ext).' -background '.$this->background.' -flatten -resize '.$dim.' '.$this->cmd_image.' '.$this->cmd_image)) { $this->errors[] = $error; return FALSE; @@ -175,7 +186,7 @@ class Image_ImageMagick_Driver extends Image_Driver { public function rotate($amt) { - if ($error = exec(escapeshellcmd($this->dir.'convert'.$this->ext).' -rotate '.escapeshellarg($amt).' -background transparent '.$this->cmd_image.' '.$this->cmd_image)) + if ($error = exec(escapeshellcmd($this->dir.'convert'.$this->ext).' -background '.$this->background.' -flatten -rotate '.escapeshellarg($amt).' -background transparent '.$this->cmd_image.' '.$this->cmd_image)) { $this->errors[] = $error; return FALSE; @@ -195,7 +206,7 @@ class Image_ImageMagick_Driver extends Image_Driver { // Convert the amount to an IM command $sharpen = escapeshellarg($radius.'x'.$sigma.'+'.$amount.'+0'); - if ($error = exec(escapeshellcmd($this->dir.'convert'.$this->ext).' -unsharp '.$sharpen.' '.$this->cmd_image.' '.$this->cmd_image)) + if ($error = exec(escapeshellcmd($this->dir.'convert'.$this->ext).' -background '.$this->background.' -flatten -unsharp '.$sharpen.' '.$this->cmd_image.' '.$this->cmd_image)) { $this->errors[] = $error; return FALSE; |