Skip to content

Instantly share code, notes, and snippets.

@ZhukV
Created May 22, 2013 07:15
Show Gist options
  • Save ZhukV/5625791 to your computer and use it in GitHub Desktop.
Save ZhukV/5625791 to your computer and use it in GitHub Desktop.
Scale & crop filter to AvalacheImagine
<?php
namespace Acme\DemoBundle\Imagine\Filter;
use Imagine\Image\BoxInterface;
use Imagine\Image\PointInterface;
use Imagine\Image\Point;
/**
* Common box container, for allowed set width or height is zero
*/
class Box implements BoxInterface
{
/**
* @var integer
*/
private $width;
/**
* @var integer
*/
private $height;
/**
* Constructs the Size with given width and height
*
* @param integer $width
* @param integer $height
*
* @throws \InvalidArgumentException
*/
public function __construct($width, $height)
{
if ($height < 0 || $width < 0) {
throw new \InvalidArgumentException(sprintf(
'Length of either side cannot be 0 or negative, current size '.
'is %sx%s', $width, $height
));
}
$this->width = (int) $width;
$this->height = (int) $height;
}
/**
* {@inheritdoc}
*/
public function getWidth()
{
return $this->width;
}
/**
* {@inheritdoc}
*/
public function getHeight()
{
return $this->height;
}
/**
* {@inheritdoc}
*/
public function scale($ratio)
{
return new Box(round($ratio * $this->width), round($ratio * $this->height));
}
/**
* {@inheritdoc}
*/
public function increase($size)
{
return new Box((int) $size + $this->width, (int) $size + $this->height);
}
/**
* {@inheritdoc}
*/
public function contains(BoxInterface $box, PointInterface $start = null)
{
$start = $start ? $start : new Point(0, 0);
return $start->in($this) &&
$this->width >= $box->getWidth() + $start->getX() &&
$this->height >= $box->getHeight() + $start->getY();
}
/**
* {@inheritdoc}
*/
public function square()
{
return $this->width * $this->height;
}
/**
* {@inheritdoc}
*/
public function __toString()
{
return sprintf('%dx%d px', $this->width, $this->height);
}
/**
* {@inheritdoc}
*/
public function widen($width)
{
return $this->scale($width / $this->width);
}
/**
* {@inheritdoc}
*/
public function heighten($height)
{
return $this->scale($height / $this->height);
}
}
<?php
namespace Acme\DemoBundle\Imagine\Filter;
use Imagine\Image\ImageInterface;
use Imagine\Filter\FilterInterface;
use Imagine\Image\Box as ImagineBox;
use Imagine\Image\Point;
/**
* Scale && Crop filter
*/
class ScaleCrop implements FilterInterface
{
/**
* @var Box
*/
protected $size;
/**
* @var bool
*/
protected $increase;
/**
* Construct
*
* @param Box $size
* @param bool $increase
*/
public function __construct(Box $size, $increase = true)
{
$this->size = $size;
$this->increase = (bool) $increase;
}
/**
* {@inheritDoc}
*
* @todo: Control increase option
*/
public function apply(ImageInterface $image)
{
if ($this->size->getWidth() && $this->size->getHeight()) {
$scale = max(
$this->size->getWidth() / $image->getSize()->getWidth(),
$this->size->getHeight() / $image->getSize()->getHeight()
);
// Create resize box
$resizeBox = new ImagineBox(
(int) $image->getSize()->getWidth() * $scale,
(int) $image->getSize()->getHeight() * $scale
);
// Resize image
$image->resize($resizeBox);
// Create crop point
$cropPoint = new Point(
(int) ($resizeBox->getWidth() - $this->size->getWidth()) / 2,
(int) ($resizeBox->getHeight() - $this->size->getHeight()) / 2
);
$image->crop($cropPoint, $this->size);
} elseif ($this->size->getWidth()) {
// Width only (Use resize filter)
$image->resize(new ImagineBox(
$this->size->getWidth(),
$image->getSize()->getHeight() / ($image->getSize()->getWidth() / $this->size->getWidth())
));
} elseif ($this->size->getHeight()) {
// Height only (Use resize filter)
$image->resize(new ImagineBox(
$image->getSize()->getWidth() / ($image->getSize()->getHeight() / $this->size->getHeight()),
$this->size->getHeight()
));
}
return $image;
}
}
<?php
namespace Acme\DemoBundle\Imagine;
use Avalanche\Bundle\ImagineBundle\Imagine\Filter\Loader\LoaderInterface;
/**
* Scale crop filter load
*/
class ScaleCropLoader implements LoaderInterface
{
/**
* {@inheritDoc}
*/
function load(array $options = array())
{
// Set default options
$options += array(
'increase' => true
);
// Set default height to zero
if (!isset($options['size'][1])) {
$options['size'][1] = 0;
}
// Get weight and height
list ($width, $height) = $options['size'];
// Create scale and crop box
$box = new Filter\Box($width, $height);
// Return filter
return new Filter\ScaleCrop($box, $options['increase']);
}
}
<?xml version="1.0" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<services>
<!-- Imagine filter loader -->
<service id="demo.imagine.scale_crop" class="Acme\DemoBundle\Imagine\ScaleCropLoader">
<tag name="imagine.filter.loader" filter="scale_crop" />
</service>
</services>
</container>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment