silverstripe-framework/filesystem/ImagickBackend.php

251 lines
5.8 KiB
PHP
Raw Normal View History

<?php
/**
* @package framework
* @subpackage filesystem
*/
if(class_exists('Imagick')) {
class ImagickBackend extends Imagick implements Image_Backend {
2014-08-15 08:53:05 +02:00
/**
* @config
* @var int
*/
private static $default_quality = 75;
2014-08-15 08:53:05 +02:00
/**
* __construct
*
* @param string $filename = null
* @param array $args = array()
* @return void
*/
public function __construct($filename = null, $args = array()) {
if(is_string($filename)) {
parent::__construct($filename);
}
$this->setQuality(Config::inst()->get('ImagickBackend','default_quality'));
}
/**
* writeTo
*
* @param string $path
* @return void
*/
public function writeTo($path) {
Filesystem::makeFolder(dirname($path));
if(is_dir(dirname($path)))
self::writeImage($path);
}
2014-08-15 08:53:05 +02:00
/**
* set_default_quality
*
* @deprecated 4.0 Use the "ImagickBackend.default_quality" config setting instead
* @param int $quality
* @return void
*/
public static function set_default_quality($quality) {
Deprecation::notice('4.0', 'Use the "ImagickBackend.default_quality" config setting instead');
if(is_numeric($quality) && (int) $quality >= 0 && (int) $quality <= 100) {
Config::inst()->update('ImagickBackend', 'default_quality', (int) $quality);
}
}
2014-08-15 08:53:05 +02:00
/**
* setQuality
*
* @param int $quality
* @return void
*/
public function setQuality($quality) {
self::setImageCompressionQuality($quality);
}
2014-08-15 08:53:05 +02:00
/**
* setImageResource
2014-08-15 08:53:05 +02:00
*
* Set the backend-specific resource handling the manipulations. Replaces Image::setGD()
*
* @param mixed $resource
* @return void
*/
public function setImageResource($resource) {
trigger_error("Imagick::setImageResource is not supported", E_USER_ERROR);
}
2014-08-15 08:53:05 +02:00
/**
* getImageResource
2014-08-15 08:53:05 +02:00
*
* Get the backend-specific resource handling the manipulations. Replaces Image::getGD()
*
* @return mixed
*/
public function getImageResource() {
return $this;
}
2014-08-15 08:53:05 +02:00
/**
* hasImageResource
*
* @return boolean
*/
public function hasImageResource() {
return true; // $this is the resource, necessarily
}
/**
* @todo Implement memory checking for Imagick? See {@link GD}
2014-08-15 08:53:05 +02:00
*
* @param string $filename
* @return boolean
*/
public function imageAvailable($filename) {
return true;
}
/**
* resize
*
* @param int $width
* @param int $height
* @return Image_Backend
*/
public function resize($width, $height) {
if(!$this->valid()) return;
if($width < 0 || $height < 0) throw new InvalidArgumentException("Image resizing dimensions cannot be negative");
if(!$width && !$height) throw new InvalidArgumentException("No dimensions given when resizing image");
if(!$width) throw new InvalidArgumentException("Width not given when resizing image");
if(!$height) throw new InvalidArgumentException("Height not given when resizing image");
//use whole numbers, ensuring that size is at least 1x1
$width = max(1, round($width));
$height = max(1, round($height));
2014-08-15 08:53:05 +02:00
$geometry = $this->getImageGeometry();
2014-08-15 08:53:05 +02:00
// Check that a resize is actually necessary.
if ($width == $geometry["width"] && $height == $geometry["height"]) {
return $this;
}
$new = clone $this;
$new->resizeImage($width, $height, self::FILTER_LANCZOS, 1);
2014-08-15 08:53:05 +02:00
return $new;
}
2014-08-15 08:53:05 +02:00
/**
* resizeRatio
*
* @param int $width
* @param int $height
* @return Image_Backend
*/
public function resizeRatio($maxWidth, $maxHeight, $useAsMinimum = false) {
if(!$this->valid()) return;
2014-08-15 08:53:05 +02:00
$geometry = $this->getImageGeometry();
2014-08-15 08:53:05 +02:00
$widthRatio = $maxWidth / $geometry["width"];
$heightRatio = $maxHeight / $geometry["height"];
2014-08-15 08:53:05 +02:00
if( $widthRatio < $heightRatio )
return $useAsMinimum ? $this->resizeByHeight( $maxHeight ) : $this->resizeByWidth( $maxWidth );
else
return $useAsMinimum ? $this->resizeByWidth( $maxWidth ) : $this->resizeByHeight( $maxHeight );
}
2014-08-15 08:53:05 +02:00
/**
* resizeByWidth
*
* @param int $width
* @return Image_Backend
*/
public function resizeByWidth($width) {
if(!$this->valid()) return;
2014-08-15 08:53:05 +02:00
$geometry = $this->getImageGeometry();
2014-08-15 08:53:05 +02:00
$heightScale = $width / $geometry["width"];
return $this->resize( $width, $heightScale * $geometry["height"] );
}
2014-08-15 08:53:05 +02:00
/**
* resizeByHeight
*
* @param int $height
* @return Image_Backend
*/
public function resizeByHeight($height) {
if(!$this->valid()) return;
2014-08-15 08:53:05 +02:00
$geometry = $this->getImageGeometry();
2014-08-15 08:53:05 +02:00
$scale = $height / $geometry["height"];
return $this->resize( $scale * $geometry["width"], $height );
}
2014-08-15 08:53:05 +02:00
/**
* paddedResize
*
* @param int $width
* @param int $height
* @return Image_Backend
*/
public function paddedResize($width, $height, $backgroundColor = "FFFFFF") {
$new = $this->resizeRatio($width, $height);
$new->setImageBackgroundColor("#".$backgroundColor);
$w = $new->getImageWidth();
$h = $new->getImageHeight();
$new->extentImage($width,$height,($w-$width)/2,($h-$height)/2);
return $new;
}
2014-08-15 08:53:05 +02:00
/**
* croppedResize
*
* @param int $width
* @param int $height
* @return Image_Backend
*/
public function croppedResize($width, $height) {
if(!$this->valid()) return;
2014-08-15 08:53:05 +02:00
$width = round($width);
$height = round($height);
2013-05-07 17:07:58 +02:00
$geo = $this->getImageGeometry();
2014-08-15 08:53:05 +02:00
// Check that a resize is actually necessary.
2013-05-07 17:07:58 +02:00
if ($width == $geo["width"] && $height == $geo["height"]) {
return $this;
}
$new = clone $this;
$new->setBackgroundColor(new ImagickPixel('transparent'));
2014-08-15 08:53:05 +02:00
2013-05-07 17:07:58 +02:00
if(($geo['width']/$width) < ($geo['height']/$height)){
2013-08-21 08:54:05 +02:00
$new->cropImage($geo['width'], floor($height*$geo['width']/$width),
0, (($geo['height']-($height*$geo['width']/$width))/2));
2013-05-07 17:07:58 +02:00
}else{
2013-08-21 08:54:05 +02:00
$new->cropImage(ceil($width*$geo['height']/$height), $geo['height'],
(($geo['width']-($width*$geo['height']/$height))/2), 0);
}
2013-05-07 17:07:58 +02:00
$new->ThumbnailImage($width,$height,true);
return $new;
}
/**
* @param Image $frontend
* @return void
*/
public function onBeforeDelete($frontend) {
// Not in use
}
}
2013-08-21 08:54:05 +02:00
}