Skip to content

Commit

Permalink
Crop Effect: Added support for ImageMagick
Browse files Browse the repository at this point in the history
Changes:
- Abstract: Added support for "gravity", "repage", and "geometry"
- Imagick: Added (untested) support for gravity
- ImageMagick: Added support for crop
  • Loading branch information
mcaskill committed Jul 13, 2017
1 parent 9f3a983 commit 683fbbe
Show file tree
Hide file tree
Showing 3 changed files with 159 additions and 20 deletions.
131 changes: 112 additions & 19 deletions src/Charcoal/Image/Effect/AbstractCropEffect.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,41 @@ abstract class AbstractCropEffect extends AbstractEffect
* @var integer $x
*/
private $x = 0;

/**
* @var integer $y
*/
private $y = 0;

/**
* @var integer $width
*/
private $width = 0;

/**
* @var integer $height
*/
private $height = 0;

/**
* @param integer $width The crop width.
* @var mixed $geometry
*/
private $geometry;

/**
* @var string $gravity
*/
private $gravity = 'center';

/**
* @var boolean $repage
*/
private $repage = false;

/**
* @param integer $width The crop width.
* @throws InvalidArgumentException If the width argument is not valid.
* @return Rotate Chainable
* @return AbstractCropEffect
*/
public function setWidth($width)
{
Expand All @@ -46,17 +64,17 @@ public function setWidth($width)
}

/**
* @return float
* @return integer
*/
public function width()
{
return $this->width;
}

/**
* @param integer $height The crop height.
* @param integer $height The crop height.
* @throws InvalidArgumentException If the height argument is not valid.
* @return $this Chainable
* @return AbstractCropEffect
*/
public function setHeight($height)
{
Expand All @@ -70,7 +88,7 @@ public function setHeight($height)
}

/**
* @return float
* @return integer
*/
public function height()
{
Expand All @@ -80,9 +98,9 @@ public function height()
/**
* The X coordinate of the cropped region's top left corner
*
* @param integer $x The x-position (in pixel) of the crop.
* @param integer $x The x-position (in pixel) of the crop.
* @throws InvalidArgumentException If the x argument is not valid.
* @return $this Chainable
* @return AbstractCropEffect
*/
public function setX($x)
{
Expand All @@ -96,7 +114,7 @@ public function setX($x)
}

/**
* @return float
* @return integer
*/
public function x()
{
Expand All @@ -106,9 +124,9 @@ public function x()
/**
* The Y coordinate of the cropped region's top left corner
*
* @param integer $y The y-position (in pixel) of the crop.
* @param integer $y The y-position (in pixel) of the crop.
* @throws InvalidArgumentException If the y argumnet is not valid.
* @return $this Chainable
* @return AbstractCropEffect
*/
public function setY($y)
{
Expand All @@ -122,26 +140,101 @@ public function setY($y)
}

/**
* @return float
* @return integer
*/
public function y()
{
return $this->y;
}

/**
* @param array $data The effect data.
* @return AbstractResizeEffect Chainable
* Set a complex geometry value.
*
* @param mixed $geometry The image geometry.
* @throws InvalidArgumentException If the geometry argument is not valid.
* @return AbstractCropEffect
*/
public function setGeometry($geometry)
{
if ($geometry !== null && !is_string($geometry) && !is_numeric($geometry)) {
throw new InvalidArgumentException(
'Geometry must be a valid crop'
);
}
$this->geometry = $geometry;
return $this;
}

/**
* Retrieve the complex geometry value.
*
* @return mixed
*/
public function geometry()
{
return $this->geometry;
}

/**
* @param string $gravity The crop gravity.
* @throws InvalidArgumentException If the argument is not a valid gravity name.
* @return AbstractCropEffect
*/
public function setGravity($gravity)
{
if (!in_array($gravity, $this->image()->availableGravities())) {
throw new InvalidArgumentException(
'Gravity is not valid'
);
}
$this->gravity = $gravity;
return $this;
}

/**
* @return string
*/
public function gravity()
{
return $this->gravity;
}

/**
* @param boolean $repage The repage image flag.
* @return AbstractCropEffect
*/
public function setRepage($repage)
{
$this->repage = !!$repage;
return $this;
}

/**
* @return boolean
*/
public function repage()
{
return $this->repage;
}

/**
* @param array $data The effect data.
* @return AbstractCropEffect
*/
public function process(array $data = null)
{
if ($data !== null) {
$this->setData($data);
}

if ($this->geometry()) {
$this->doCrop(0, 0, 0, 0);
return $this;
}

$y = $this->y();
$x = $this->x();
$width = $this->width();
$width = $this->width();
$height = $this->height();

$this->doCrop($width, $height, $x, $y);
Expand All @@ -150,10 +243,10 @@ public function process(array $data = null)
}

/**
* @param integer $width The crop width.
* @param integer $height The crop height.
* @param integer $x The x-position (in pixel) of the crop.
* @param integer $y The y-position (in pixel) of the crop.
* @param integer $width The crop width.
* @param integer $height The crop height.
* @param integer $x The x-position (in pixel) of the crop.
* @param integer $y The y-position (in pixel) of the crop.
* @return void
*/
abstract protected function doCrop($width, $height, $x, $y);
Expand Down
44 changes: 44 additions & 0 deletions src/Charcoal/Image/Imagemagick/Effect/ImagemagickCropEffect.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php

namespace Charcoal\Image\Imagemagick\Effect;

use \Exception;

use \Charcoal\Image\Effect\AbstractCropEffect;

/**
* Reisze Effect for the Imagemagick driver.
*
* See {@link http://www.imagemagick.org/script/command-line-processing.php#geometry Image Geometry}
* for complete details about the geometry argument.
*/
class ImagemagickCropEffect extends AbstractCropEffect
{
/**
* @param integer $width The crop width.
* @param integer $height The crop height.
* @param integer $x The x-position (in pixel) of the crop.
* @param integer $y The y-position (in pixel) of the crop.
* @return void
*/
protected function doCrop($width, $height, $x, $y)
{
$option = '-crop';

$geometry = $this->geometry();
if ($geometry) {
$params = [ $option.' '.$geometry ];
} else {
$params = [ '-gravity "'.$this->gravity().'"' ];

$size = $width.'x'.$height.($x >= 0 ? '+' : '').$x.($y >= 0 ? '+' : '').$y;
$params[] = $option.' '.$size;
}

if ($this->repage()) {
$params[] = '+repage';
}

$this->image()->applyCmd(implode(' ', $params));
}
}
4 changes: 3 additions & 1 deletion src/Charcoal/Image/Imagick/Effect/ImagickCropEffect.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ class ImagickCropEffect extends AbstractCropEffect
*/
protected function doCrop($width, $height, $x, $y)
{
$this->image()->imagick()->cropImage($width, $height, $x, $y);
$gravity = $this->image()->imagickGravity($this->gravity());

$this->image()->imagick()->setGravity($gravity)->cropImage($width, $height, $x, $y);
}
}

0 comments on commit 683fbbe

Please sign in to comment.