summaryrefslogtreecommitdiff
path: root/system/libraries/drivers/Image
diff options
context:
space:
mode:
Diffstat (limited to 'system/libraries/drivers/Image')
-rw-r--r--system/libraries/drivers/Image/GD.php69
-rw-r--r--system/libraries/drivers/Image/GraphicsMagick.php14
-rw-r--r--system/libraries/drivers/Image/ImageMagick.php39
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;