Upgrade to KH 3.3.0

This commit is contained in:
Deon George
2012-11-22 14:25:06 +11:00
parent e5e67a59bb
commit 5bd1841571
1455 changed files with 114353 additions and 9466 deletions

View File

@@ -0,0 +1,3 @@
<?php defined('SYSPATH') OR die('No direct script access.');
abstract class Image extends Kohana_Image {}

View File

@@ -0,0 +1,3 @@
<?php defined('SYSPATH') OR die('No direct script access.');
class Image_GD extends Kohana_Image_GD {}

View File

@@ -0,0 +1,3 @@
<?php defined('SYSPATH') OR die('No direct script access.');
class Image_Imagick extends Kohana_Image_Imagick {}

View File

@@ -1,4 +1,4 @@
<?php defined('SYSPATH') or die('No direct script access.');
<?php defined('SYSPATH') OR die('No direct script access.');
/**
* Image manipulation support. Allows images to be resized, cropped, etc.
*
@@ -16,6 +16,7 @@ abstract class Kohana_Image {
const HEIGHT = 0x03;
const AUTO = 0x04;
const INVERSE = 0x05;
const PRECISE = 0x06;
// Flipping directions
const HORIZONTAL = 0x11;
@@ -34,8 +35,8 @@ abstract class Kohana_Image {
*
* $image = Image::factory('upload/test.jpg');
*
* @param string image file path
* @param string driver type: GD, ImageMagick, etc
* @param string $file image file path
* @param string $driver driver type: GD, ImageMagick, etc
* @return Image
* @uses Image::$default_driver
*/
@@ -82,7 +83,7 @@ abstract class Kohana_Image {
* Loads information about the image. Will throw an exception if the image
* does not exist or is not an image.
*
* @param string image file path
* @param string $file image file path
* @return void
* @throws Kohana_Exception
*/
@@ -167,9 +168,9 @@ abstract class Kohana_Image {
* // Resize to 200x500 pixels, ignoring aspect ratio
* $image->resize(200, 500, Image::NONE);
*
* @param integer new width
* @param integer new height
* @param integer master dimension
* @param integer $width new width
* @param integer $height new height
* @param integer $master master dimension
* @return $this
* @uses Image::_do_resize
*/
@@ -247,6 +248,19 @@ abstract class Kohana_Image {
// Recalculate the width based on the height proportions
$width = $this->width * $height / $this->height;
break;
case Image::PRECISE:
// Resize to precise size
$ratio = $this->width / $this->height;
if ($width / $height > $ratio)
{
$height = $this->height * $width / $this->width;
}
else
{
$width = $this->width * $height / $this->height;
}
break;
}
// Convert the width and height to integers, minimum value is 1px
@@ -268,10 +282,10 @@ abstract class Kohana_Image {
* // Crop the image to 200x200 pixels, from the center
* $image->crop(200, 200);
*
* @param integer new width
* @param integer new height
* @param mixed offset from the left
* @param mixed offset from the top
* @param integer $width new width
* @param integer $height new height
* @param mixed $offset_x offset from the left
* @param mixed $offset_y offset from the top
* @return $this
* @uses Image::_do_crop
*/
@@ -351,7 +365,7 @@ abstract class Kohana_Image {
* // Rotate 90% counter-clockwise
* $image->rotate(-90);
*
* @param integer degrees to rotate: -360-360
* @param integer $degrees degrees to rotate: -360-360
* @return $this
* @uses Image::_do_rotate
*/
@@ -367,7 +381,7 @@ abstract class Kohana_Image {
// Keep subtracting full circles until the degrees have normalized
$degrees -= 360;
}
while($degrees > 180);
while ($degrees > 180);
}
if ($degrees < -180)
@@ -377,7 +391,7 @@ abstract class Kohana_Image {
// Keep adding full circles until the degrees have normalized
$degrees += 360;
}
while($degrees < -180);
while ($degrees < -180);
}
$this->_do_rotate($degrees);
@@ -394,7 +408,7 @@ abstract class Kohana_Image {
* // Flip the image from left to right
* $image->flip(Image::VERTICAL);
*
* @param integer direction: Image::HORIZONTAL, Image::VERTICAL
* @param integer $direction direction: Image::HORIZONTAL, Image::VERTICAL
* @return $this
* @uses Image::_do_flip
*/
@@ -417,7 +431,7 @@ abstract class Kohana_Image {
* // Sharpen the image by 20%
* $image->sharpen(20);
*
* @param integer amount to sharpen: 1-100
* @param integer $amount amount to sharpen: 1-100
* @return $this
* @uses Image::_do_sharpen
*/
@@ -448,9 +462,9 @@ abstract class Kohana_Image {
* [!!] By default, the reflection will be go from transparent at the top
* to opaque at the bottom.
*
* @param integer reflection height
* @param integer reflection opacity: 0-100
* @param boolean TRUE to fade in, FALSE to fade out
* @param integer $height reflection height
* @param integer $opacity reflection opacity: 0-100
* @param boolean $fade_in TRUE to fade in, FALSE to fade out
* @return $this
* @uses Image::_do_reflection
*/
@@ -481,10 +495,10 @@ abstract class Kohana_Image {
* $mark = Image::factory('upload/watermark.png');
* $image->watermark($mark, TRUE, TRUE);
*
* @param object watermark Image instance
* @param integer offset from the left
* @param integer offset from the top
* @param integer opacity of watermark: 1-100
* @param Image $watermark watermark Image instance
* @param integer $offset_x offset from the left
* @param integer $offset_y offset from the top
* @param integer $opacity opacity of watermark: 1-100
* @return $this
* @uses Image::_do_watermark
*/
@@ -540,8 +554,8 @@ abstract class Kohana_Image {
* // Make the image background black with 50% opacity
* $image->background('#000', 50);
*
* @param string hexadecimal color value
* @param integer background opacity: 0-100
* @param string $color hexadecimal color value
* @param integer $opacity background opacity: 0-100
* @return $this
* @uses Image::_do_background
*/
@@ -585,8 +599,8 @@ abstract class Kohana_Image {
* [!!] If the file does not exist, and the directory is not writable, an
* exception will be thrown.
*
* @param string new image path
* @param integer quality of image: 1-100
* @param string $file new image path
* @param integer $quality quality of image: 1-100
* @return boolean
* @uses Image::_save
* @throws Kohana_Exception
@@ -634,8 +648,8 @@ abstract class Kohana_Image {
* // Render the image as a PNG
* $data = $image->render('png');
*
* @param string image type to return: png, jpg, gif, etc
* @param integer quality of image: 1-100
* @param string $type image type to return: png, jpg, gif, etc
* @param integer $quality quality of image: 1-100
* @return string
* @uses Image::_do_render
*/
@@ -653,8 +667,8 @@ abstract class Kohana_Image {
/**
* Execute a resize.
*
* @param integer new width
* @param integer new height
* @param integer $width new width
* @param integer $height new height
* @return void
*/
abstract protected function _do_resize($width, $height);
@@ -662,10 +676,10 @@ abstract class Kohana_Image {
/**
* Execute a crop.
*
* @param integer new width
* @param integer new height
* @param integer offset from the left
* @param integer offset from the top
* @param integer $width new width
* @param integer $height new height
* @param integer $offset_x offset from the left
* @param integer $offset_y offset from the top
* @return void
*/
abstract protected function _do_crop($width, $height, $offset_x, $offset_y);
@@ -673,7 +687,7 @@ abstract class Kohana_Image {
/**
* Execute a rotation.
*
* @param integer degrees to rotate
* @param integer $degrees degrees to rotate
* @return void
*/
abstract protected function _do_rotate($degrees);
@@ -681,7 +695,7 @@ abstract class Kohana_Image {
/**
* Execute a flip.
*
* @param integer direction to flip
* @param integer $direction direction to flip
* @return void
*/
abstract protected function _do_flip($direction);
@@ -689,7 +703,7 @@ abstract class Kohana_Image {
/**
* Execute a sharpen.
*
* @param integer amount to sharpen
* @param integer $amount amount to sharpen
* @return void
*/
abstract protected function _do_sharpen($amount);
@@ -697,9 +711,9 @@ abstract class Kohana_Image {
/**
* Execute a reflection.
*
* @param integer reflection height
* @param integer reflection opacity
* @param boolean TRUE to fade out, FALSE to fade in
* @param integer $height reflection height
* @param integer $opacity reflection opacity
* @param boolean $fade_in TRUE to fade out, FALSE to fade in
* @return void
*/
abstract protected function _do_reflection($height, $opacity, $fade_in);
@@ -707,10 +721,10 @@ abstract class Kohana_Image {
/**
* Execute a watermarking.
*
* @param object watermarking Image
* @param integer offset from the left
* @param integer offset from the top
* @param integer opacity of watermark
* @param Image $image watermarking Image
* @param integer $offset_x offset from the left
* @param integer $offset_y offset from the top
* @param integer $opacity opacity of watermark
* @return void
*/
abstract protected function _do_watermark(Image $image, $offset_x, $offset_y, $opacity);
@@ -718,10 +732,10 @@ abstract class Kohana_Image {
/**
* Execute a background.
*
* @param integer red
* @param integer green
* @param integer blue
* @param integer opacity
* @param integer $r red
* @param integer $g green
* @param integer $b blue
* @param integer $opacity opacity
* @return void
*/
abstract protected function _do_background($r, $g, $b, $opacity);
@@ -729,8 +743,8 @@ abstract class Kohana_Image {
/**
* Execute a save.
*
* @param string new image filename
* @param integer quality
* @param string $file new image filename
* @param integer $quality quality
* @return boolean
*/
abstract protected function _do_save($file, $quality);
@@ -738,8 +752,8 @@ abstract class Kohana_Image {
/**
* Execute a render.
*
* @param string image type: png, jpg, gif, etc
* @param integer quality
* @param string $type image type: png, jpg, gif, etc
* @param integer $quality quality
* @return string
*/
abstract protected function _do_render($type, $quality);

View File

@@ -1,4 +1,4 @@
<?php defined('SYSPATH') or die('No direct script access.');
<?php defined('SYSPATH') OR die('No direct script access.');
/**
* Support for image manipulation using [GD](http://php.net/GD).
*
@@ -76,6 +76,7 @@ class Kohana_Image_GD extends Image {
/**
* Runs [Image_GD::check] and loads the image.
*
* @param string $file image file path
* @return void
* @throws Kohana_Exception
*/
@@ -150,6 +151,13 @@ class Kohana_Image_GD extends Image {
}
}
/**
* Execute a resize.
*
* @param integer $width new width
* @param integer $height new height
* @return void
*/
protected function _do_resize($width, $height)
{
// Presize width and height
@@ -200,6 +208,15 @@ class Kohana_Image_GD extends Image {
}
}
/**
* Execute a crop.
*
* @param integer $width new width
* @param integer $height new height
* @param integer $offset_x offset from the left
* @param integer $offset_y offset from the top
* @return void
*/
protected function _do_crop($width, $height, $offset_x, $offset_y)
{
// Create the temporary image to copy to
@@ -221,6 +238,12 @@ class Kohana_Image_GD extends Image {
}
}
/**
* Execute a rotation.
*
* @param integer $degrees degrees to rotate
* @return void
*/
protected function _do_rotate($degrees)
{
if ( ! Image_GD::$_bundled)
@@ -257,6 +280,12 @@ class Kohana_Image_GD extends Image {
}
}
/**
* Execute a flip.
*
* @param integer $direction direction to flip
* @return void
*/
protected function _do_flip($direction)
{
// Create the flipped image
@@ -291,6 +320,12 @@ class Kohana_Image_GD extends Image {
$this->height = imagesy($flipped);
}
/**
* Execute a sharpen.
*
* @param integer $amount amount to sharpen
* @return void
*/
protected function _do_sharpen($amount)
{
if ( ! Image_GD::$_bundled)
@@ -322,6 +357,14 @@ class Kohana_Image_GD extends Image {
}
}
/**
* Execute a reflection.
*
* @param integer $height reflection height
* @param integer $opacity reflection opacity
* @param boolean $fade_in TRUE to fade out, FALSE to fade in
* @return void
*/
protected function _do_reflection($height, $opacity, $fade_in)
{
if ( ! Image_GD::$_bundled)
@@ -394,6 +437,15 @@ class Kohana_Image_GD extends Image {
$this->height = imagesy($reflection);
}
/**
* Execute a watermarking.
*
* @param Image $image watermarking Image
* @param integer $offset_x offset from the left
* @param integer $offset_y offset from the top
* @param integer $opacity opacity of watermark
* @return void
*/
protected function _do_watermark(Image $watermark, $offset_x, $offset_y, $opacity)
{
if ( ! Image_GD::$_bundled)
@@ -439,6 +491,15 @@ class Kohana_Image_GD extends Image {
}
}
/**
* Execute a background.
*
* @param integer $r red
* @param integer $g green
* @param integer $b blue
* @param integer $opacity opacity
* @return void
*/
protected function _do_background($r, $g, $b, $opacity)
{
// Loads image if not yet loaded
@@ -468,6 +529,13 @@ class Kohana_Image_GD extends Image {
}
}
/**
* Execute a save.
*
* @param string $file new image filename
* @param integer $quality quality
* @return boolean
*/
protected function _do_save($file, $quality)
{
// Loads image if not yet loaded
@@ -492,6 +560,13 @@ class Kohana_Image_GD extends Image {
return TRUE;
}
/**
* Execute a render.
*
* @param string $type image type: png, jpg, gif, etc
* @param integer $quality quality
* @return string
*/
protected function _do_render($type, $quality)
{
// Loads image if not yet loaded
@@ -520,13 +595,19 @@ class Kohana_Image_GD extends Image {
* Get the GD saving function and image type for this extension.
* Also normalizes the quality setting
*
* @param string image type: png, jpg, etc
* @param integer image quality
* @param string $extension image type: png, jpg, etc
* @param integer $quality image quality
* @return array save function, IMAGETYPE_* constant
* @throws Kohana_Exception
*/
protected function _save_function($extension, & $quality)
{
if ( ! $extension)
{
// Use the current image type
$extension = image_type_to_extension($this->type, FALSE);
}
switch (strtolower($extension))
{
case 'jpg':
@@ -563,8 +644,8 @@ class Kohana_Image_GD extends Image {
/**
* Create an empty image with the given width and height.
*
* @param integer image width
* @param integer image height
* @param integer $width image width
* @param integer $height image height
* @return resource
*/
protected function _create($width, $height)

View File

@@ -0,0 +1,334 @@
<?php defined('SYSPATH') OR die('No direct script access.');
/**
* Support for image manipulation using [Imagick](http://php.net/Imagick).
*
* @package Kohana/Image
* @category Drivers
* @author Tamas Mihalik tamas.mihalik@gmail.com
* @copyright (c) 2009-2012 Kohana Team
* @license http://kohanaphp.com/license.html
*/
class Kohana_Image_Imagick extends Image {
/**
* @var Imagick image magick object
*/
protected $im;
/**
* Checks if ImageMagick is enabled.
*
* @throws Kohana_Exception
* @return boolean
*/
public static function check()
{
if ( ! extension_loaded('imagick'))
{
throw new Kohana_Exception('Imagick is not installed, or the extension is not loaded');
}
return Image_Imagick::$_checked = TRUE;
}
/**
* Runs [Image_Imagick::check] and loads the image.
*
* @return void
* @throws Kohana_Exception
*/
public function __construct($file)
{
if ( ! Image_Imagick::$_checked)
{
// Run the install check
Image_Imagick::check();
}
parent::__construct($file);
$this->im = new Imagick;
$this->im->readImage($file);
if ( ! $this->im->getImageAlphaChannel())
{
// Force the image to have an alpha channel
$this->im->setImageAlphaChannel(Imagick::ALPHACHANNEL_SET);
}
}
/**
* Destroys the loaded image to free up resources.
*
* @return void
*/
public function __destruct()
{
$this->im->clear();
$this->im->destroy();
}
protected function _do_resize($width, $height)
{
if ($this->im->scaleImage($width, $height))
{
// Reset the width and height
$this->width = $this->im->getImageWidth();
$this->height = $this->im->getImageHeight();
return TRUE;
}
return FALSE;
}
protected function _do_crop($width, $height, $offset_x, $offset_y)
{
if ($this->im->cropImage($width, $height, $offset_x, $offset_y))
{
// Reset the width and height
$this->width = $this->im->getImageWidth();
$this->height = $this->im->getImageHeight();
// Trim off hidden areas
$this->im->setImagePage($this->width, $this->height, 0, 0);
return TRUE;
}
return FALSE;
}
protected function _do_rotate($degrees)
{
if ($this->im->rotateImage(new ImagickPixel('transparent'), $degrees))
{
// Reset the width and height
$this->width = $this->im->getImageWidth();
$this->height = $this->im->getImageHeight();
// Trim off hidden areas
$this->im->setImagePage($this->width, $this->height, 0, 0);
return TRUE;
}
return FALSE;
}
protected function _do_flip($direction)
{
if ($direction === Image::HORIZONTAL)
{
return $this->im->flopImage();
}
else
{
return $this->im->flipImage();
}
}
protected function _do_sharpen($amount)
{
// IM not support $amount under 5 (0.15)
$amount = ($amount < 5) ? 5 : $amount;
// Amount should be in the range of 0.0 to 3.0
$amount = ($amount * 3.0) / 100;
return $this->im->sharpenImage(0, $amount);
}
protected function _do_reflection($height, $opacity, $fade_in)
{
// Clone the current image and flip it for reflection
$reflection = $this->im->clone();
$reflection->flipImage();
// Crop the reflection to the selected height
$reflection->cropImage($this->width, $height, 0, 0);
$reflection->setImagePage($this->width, $height, 0, 0);
// Select the fade direction
$direction = array('transparent', 'black');
if ($fade_in)
{
// Change the direction of the fade
$direction = array_reverse($direction);
}
// Create a gradient for fading
$fade = new Imagick;
$fade->newPseudoImage($reflection->getImageWidth(), $reflection->getImageHeight(), vsprintf('gradient:%s-%s', $direction));
// Apply the fade alpha channel to the reflection
$reflection->compositeImage($fade, Imagick::COMPOSITE_DSTOUT, 0, 0);
// NOTE: Using setImageOpacity will destroy alpha channels!
$reflection->evaluateImage(Imagick::EVALUATE_MULTIPLY, $opacity / 100, Imagick::CHANNEL_ALPHA);
// Create a new container to hold the image and reflection
$image = new Imagick;
$image->newImage($this->width, $this->height + $height, new ImagickPixel);
// Force the image to have an alpha channel
$image->setImageAlphaChannel(Imagick::ALPHACHANNEL_SET);
// Force the background color to be transparent
// $image->setImageBackgroundColor(new ImagickPixel('transparent'));
// Match the colorspace between the two images before compositing
$image->setColorspace($this->im->getColorspace());
// Place the image and reflection into the container
if ($image->compositeImage($this->im, Imagick::COMPOSITE_SRC, 0, 0)
AND $image->compositeImage($reflection, Imagick::COMPOSITE_OVER, 0, $this->height))
{
// Replace the current image with the reflected image
$this->im = $image;
// Reset the width and height
$this->width = $this->im->getImageWidth();
$this->height = $this->im->getImageHeight();
return TRUE;
}
return FALSE;
}
protected function _do_watermark(Image $image, $offset_x, $offset_y, $opacity)
{
// Convert the Image intance into an Imagick instance
$watermark = new Imagick;
$watermark->readImageBlob($image->render(), $image->file);
if ($watermark->getImageAlphaChannel() !== Imagick::ALPHACHANNEL_ACTIVATE)
{
// Force the image to have an alpha channel
$watermark->setImageAlphaChannel(Imagick::ALPHACHANNEL_OPAQUE);
}
if ($opacity < 100)
{
// NOTE: Using setImageOpacity will destroy current alpha channels!
$watermark->evaluateImage(Imagick::EVALUATE_MULTIPLY, $opacity / 100, Imagick::CHANNEL_ALPHA);
}
// Match the colorspace between the two images before compositing
// $watermark->setColorspace($this->im->getColorspace());
// Apply the watermark to the image
return $this->im->compositeImage($watermark, Imagick::COMPOSITE_DISSOLVE, $offset_x, $offset_y);
}
protected function _do_background($r, $g, $b, $opacity)
{
// Create a RGB color for the background
$color = sprintf('rgb(%d, %d, %d)', $r, $g, $b);
// Create a new image for the background
$background = new Imagick;
$background->newImage($this->width, $this->height, new ImagickPixel($color));
if ( ! $background->getImageAlphaChannel())
{
// Force the image to have an alpha channel
$background->setImageAlphaChannel(Imagick::ALPHACHANNEL_SET);
}
// Clear the background image
$background->setImageBackgroundColor(new ImagickPixel('transparent'));
// NOTE: Using setImageOpacity will destroy current alpha channels!
$background->evaluateImage(Imagick::EVALUATE_MULTIPLY, $opacity / 100, Imagick::CHANNEL_ALPHA);
// Match the colorspace between the two images before compositing
$background->setColorspace($this->im->getColorspace());
if ($background->compositeImage($this->im, Imagick::COMPOSITE_DISSOLVE, 0, 0))
{
// Replace the current image with the new image
$this->im = $background;
return TRUE;
}
return FALSE;
}
protected function _do_save($file, $quality)
{
// Get the image format and type
list($format, $type) = $this->_get_imagetype(pathinfo($file, PATHINFO_EXTENSION));
// Set the output image type
$this->im->setFormat($format);
// Set the output quality
$this->im->setImageCompressionQuality($quality);
if ($this->im->writeImage($file))
{
// Reset the image type and mime type
$this->type = $type;
$this->mime = image_type_to_mime_type($type);
return TRUE;
}
return FALSE;
}
protected function _do_render($type, $quality)
{
// Get the image format and type
list($format, $type) = $this->_get_imagetype($type);
// Set the output image type
$this->im->setFormat($format);
// Set the output quality
$this->im->setImageCompressionQuality($quality);
// Reset the image type and mime type
$this->type = $type;
$this->mime = image_type_to_mime_type($type);
return (string) $this->im;
}
/**
* Get the image type and format for an extension.
*
* @param string $extension image extension: png, jpg, etc
* @return string IMAGETYPE_* constant
* @throws Kohana_Exception
*/
protected function _get_imagetype($extension)
{
// Normalize the extension to a format
$format = strtolower($extension);
switch ($format)
{
case 'jpg':
case 'jpeg':
$type = IMAGETYPE_JPEG;
break;
case 'gif':
$type = IMAGETYPE_GIF;
break;
case 'png':
$type = IMAGETYPE_PNG;
break;
default:
throw new Kohana_Exception('Installed ImageMagick does not support :type images',
array(':type' => $extension));
break;
}
return array($format, $type);
}
} // End Kohana_Image_Imagick

View File

@@ -1,3 +0,0 @@
<?php defined('SYSPATH') or die('No direct script access.');
abstract class Image extends Kohana_Image {}

View File

@@ -1,3 +0,0 @@
<?php defined('SYSPATH') or die('No direct script access.');
class Image_GD extends Kohana_Image_GD {}