Файл: library/XenForo/Image/ImageMagick/Pecl.php
Строк: 177
<?php
/**
* Image processor using imagick PECL extension.
*
* @package XenForo_Image
* @author SMV
*/
class XenForo_Image_ImageMagick_Pecl extends XenForo_Image_Abstract
{
/**
* The Imagick object
*
* @var Imagick
*/
protected $_image = null;
/**
* Constructor.
*
* @param resource $image Imagick object
*/
protected function __construct(Imagick $image)
{
$this->_setImage($image);
}
public function __destruct()
{
if ($this->_image) {
$this->_image->destroy();
}
}
/**
* Creates a blank image.
*
* @param integer $width
* @param integer $height
*
* @return XenForo_Image_Imagemagick_Pecl
*/
public static function createImageDirect($width, $height)
{
$instance = new Imagick();
// background colour is transparent with none
$instance->newImage($width, $height, new ImagickPixel('none'));
$class = XenForo_Application::resolveDynamicClass(__CLASS__);
return new $class($instance);
}
/**
* Creates an image from an existing file.
*
* @param string $fileName
* @param integer $inputType IMAGETYPE_XYZ constant representing image type
*
* @return XenForo_Image_Imagemagick_Pecl|false
*/
public static function createFromFileDirect($fileName, $inputType)
{
$invalidType = false;
try
{
switch ($inputType)
{
case IMAGETYPE_GIF:
case IMAGETYPE_JPEG:
case IMAGETYPE_PNG:
$image = new Imagick($fileName);
break;
default:
$invalidType = true;
}
}
catch (Exception $e)
{
return false;
}
if ($invalidType)
{
throw new XenForo_Exception('Invalid image type given. Expects IMAGETYPE_XXX constant.');
}
$class = XenForo_Application::resolveDynamicClass(__CLASS__);
return new $class($image);
}
/**
* Thumbnails the image.
*
* @see XenForo_Image_Abstract::thumbnail()
*/
public function thumbnail($maxWidth, $maxHeight = 0)
{
if ($maxWidth < 10)
{
$maxWidth = 10;
}
if ($maxHeight < 10)
{
$maxHeight = $maxWidth;
}
if ($this->_width < $maxWidth && $this->_height < $maxHeight)
{
return false;
}
$ratio = $this->_width / $this->_height;
$maxRatio = ($maxWidth / $maxHeight);
if ($maxRatio > $ratio)
{
$width = max(1, $maxHeight * $ratio);
$height = $maxHeight;
}
else
{
$width = $maxWidth;
$height = max(1, $maxWidth / $ratio);
}
try
{
foreach ($this->_image AS $frame)
{
$frame->thumbnailImage($width, $height, true);
$frame->setImagePage($frame->getImageWidth(), $frame->getImageHeight(), 0, 0);
}
$this->_updateDimensionCache();
}
catch (Exception $e)
{
return false;
}
return true;
}
/**
* Produces a thumbnail of the current image whose shorter side is the specified length
*
* @see XenForo_Image_Abstract::thumbnailFixedShorterSide
*/
public function thumbnailFixedShorterSide($shortSideLength)
{
if ($shortSideLength < 10)
{
$shortSideLength = 10;
}
$scaleUp = false;
$ratio = $this->_width / $this->_height;
if ($ratio > 1) // landscape
{
$width = ceil($shortSideLength * $ratio);
$height = $shortSideLength;
$scaleUp = ($this->_height < $height);
}
else
{
$width = $shortSideLength;
$height = ceil(max(1, $shortSideLength / $ratio));
$scaleUp = ($this->_width < $width);
}
// imagick module < 3 or ImageMagick < 6.3.2 don't support the 4th thumbnailImage param
$oldImagick = version_compare(phpversion('imagick'), '3', '<');
$version = $this->_image->getVersion();
if (preg_match('#ImageMagick (d+.d+.d+)#i', $version['versionString'], $match))
{
if (version_compare($match[1], '6.3.2', '<'))
{
$oldImagick = true;
}
}
try
{
foreach ($this->_image AS $frame)
{
if ($scaleUp)
{
$frame->resizeImage($width, $height, Imagick::FILTER_QUADRATIC, .5, true);
}
else if ($oldImagick)
{
$frame->thumbnailImage($width, $height, true);
}
else
{
$frame->thumbnailImage($width, $height, true, true);
}
$frame->setImagePage($width, $height, 0, 0);
}
$this->_updateDimensionCache();
}
catch (Exception $e)
{
return false;
}
}
/**
* Crops the image.
*
* @see XenForo_Image_Abstract::crop()
*/
public function crop($x, $y, $width, $height)
{
foreach ($this->_image AS $frame)
{
$frame->cropImage($width, $height, $x, $y);
$frame->setImagePage($frame->getImageWidth(), $frame->getImageHeight(), 0, 0);
}
$this->_updateDimensionCache();
}
/**
* Rotates the image clockwise
*
* @see XenForo_Image_Abstract::rotate()
*/
public function rotate($angle)
{
foreach ($this->_image AS $frame)
{
$frame->rotateImage(new ImagickPixel('none'), $angle);
}
$this->_updateDimensionCache();
}
/**
* Flips the image
*
* @see XenForo_Image_Abstract::flip()
*/
public function flip($mode)
{
foreach ($this->_image AS $frame)
{
switch ($mode)
{
case self::FLIP_HORIZONTAL:
$frame->flopImage();
break;
case self::FLIP_VERTICAL:
$frame->flipImage();
break;
case self::FLIP_BOTH:
$frame->flopImage();
$frame->flipImage();
break;
default:
return;
}
}
$this->_updateDimensionCache();
}
/**
* Outputs the image.
*
* @see XenForo_Image_Abstract::output()
*/
public function output($outputType, $outputFile = null, $quality = 85)
{
$this->_image->stripImage();
// NULL means output directly
switch ($outputType)
{
case IMAGETYPE_GIF:
if (is_callable(array($this->_image, 'optimizeimagelayers')))
{
$this->_image->optimizeimagelayers();
}
$success = $this->_image->setImageFormat('gif');
break;
case IMAGETYPE_JPEG:
$success = $this->_image->setImageFormat('jpeg')
&& $this->_image->setImageCompression(Imagick::COMPRESSION_JPEG)
&& $this->_image->setImageCompressionQuality($quality);
break;
case IMAGETYPE_PNG:
$success = $this->_image->setImageFormat('png');
break;
default:
throw new XenForo_Exception('Invalid output type given. Expects IMAGETYPE_XXX constant.');
}
try
{
if ($success)
{
if (!$outputFile)
{
echo $this->_image->getImagesBlob();
}
else
{
$success = $this->_image->writeImages($outputFile, true);
}
}
}
catch (ImagickException $e)
{
return false;
}
return $success;
}
/**
* Sets the internal Imagick object
*
* @param resource $image
*/
protected function _setImage(Imagick $image)
{
$this->_image = $image->coalesceImages();
$this->_updateDimensionCache();
}
/**
* Update the cached dimension information from
* the internal Imagick object
*
*/
protected function _updateDimensionCache()
{
$this->_width = $this->_image->getImageWidth();
$this->_height = $this->_image->getImageHeight();
}
}