Skip to content

Commit

Permalink
add resample filter implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
robfrawley committed May 23, 2017
1 parent d2551d8 commit 1d71c29
Show file tree
Hide file tree
Showing 8 changed files with 435 additions and 12 deletions.
6 changes: 3 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,17 +50,17 @@ matrix:

before_install:
- if [ "${TRAVIS_PHP_VERSION}" != "hhvm" ]; then echo "memory_limit = -1" >> ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini; fi;
- cp ./.composer/config.json ~/.composer; composer global require "hirak/prestissimo:^0.3"
- cp ./.composer/config.json ~/.composer; composer global require "hirak/prestissimo:^0.3" -vvvss
- if [ "${TRAVIS_PHP_VERSION}" == "5.3" ]; then composer remove --no-update --dev satooshi/php-coveralls; fi;
- if [ "${SYMFONY_VERSION:0:3}" == "2.3" ]; then composer remove --no-update --dev friendsofphp/php-cs-fixer; fi;
- if [ "${SYMFONY_VERSION:-x}" != "x" ]; then composer require "symfony/symfony:${SYMFONY_VERSION}" --no-update; fi;
- if [ "${TRAVIS_PHP_VERSION}" != "hhvm" ] && [ "${TRAVIS_PHP_VERSION:0:3}" != "5.3" ]; then composer require --no-update --dev league/flysystem:~1.0; fi;
- if [ "${TRAVIS_PHP_VERSION}" != "hhvm" ] && [ "${TRAVIS_PHP_VERSION:0:1}" != "7" ]; then yes "" | pecl -q install -f mongo; composer require --no-update --dev doctrine/mongodb-odm:~1.0; fi;
- if [ "${TRAVIS_PHP_VERSION}" != "hhvm" ] && [ "${TRAVIS_PHP_VERSION:0:1}" == "7" ]; then yes "" | pecl -q install -f mongodb; travis_retry composer require --dev alcaeus/mongo-php-adapter:~1.0; composer require --no-update --dev doctrine/mongodb-odm:~1.0; fi
- if [ "${TRAVIS_PHP_VERSION}" != "hhvm" ] && [ "${TRAVIS_PHP_VERSION:0:1}" == "7" ]; then yes "" | pecl -q install -f mongodb; travis_retry composer require --dev alcaeus/mongo-php-adapter:~1.0 -vvv; composer require --no-update --dev doctrine/mongodb-odm:~1.0; fi
- if [ "$WITH_ENQUEUE" = true ] ; then composer require --no-update --dev enqueue/enqueue-bundle:^0.3.6; fi;

install:
- travis_retry composer update $COMPOSER_FLAGS
- travis_retry composer update $COMPOSER_FLAGS -vvv

script:
- bin/simple-phpunit -vvv || bin/phpunit -vvv
Expand Down
18 changes: 18 additions & 0 deletions Exception/Imagine/Filter/LoadFilterException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

/*
* This file is part of the `liip/LiipImagineBundle` project.
*
* (c) https://github.com/liip/LiipImagineBundle/graphs/contributors
*
* For the full copyright and license information, please view the LICENSE.md
* file that was distributed with this source code.
*/

namespace Liip\ImagineBundle\Exception\Imagine\Filter;

use Liip\ImagineBundle\Exception\ExceptionInterface;

class LoadFilterException extends \RuntimeException implements ExceptionInterface
{
}
172 changes: 172 additions & 0 deletions Imagine/Filter/Loader/ResampleFilterLoader.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
<?php

/*
* This file is part of the `liip/LiipImagineBundle` project.
*
* (c) https://github.com/liip/LiipImagineBundle/graphs/contributors
*
* For the full copyright and license information, please view the LICENSE.md
* file that was distributed with this source code.
*/

namespace Liip\ImagineBundle\Imagine\Filter\Loader;

use Imagine\Image\ImageInterface;
use Imagine\Image\ImagineInterface;
use Liip\ImagineBundle\Exception\Imagine\Filter\LoadFilterException;
use Liip\ImagineBundle\Utility\OptionsResolver\OptionsResolver;
use Liip\ImagineBundle\Exception\InvalidArgumentException;
use Symfony\Component\OptionsResolver\Options;
use Symfony\Component\OptionsResolver\Exception\ExceptionInterface;

class ResampleFilterLoader implements LoaderInterface
{
/**
* @var ImagineInterface
*/
private $imagine;

/**
* @param ImagineInterface $imagine
*/
public function __construct(ImagineInterface $imagine)
{
$this->imagine = $imagine;
}

/**
* @param ImageInterface $image
* @param array $options
*
* @throws LoadFilterException
*
* @return ImageInterface
*/
public function load(ImageInterface $image, array $options = array())
{
$options = $this->resolveOptions($options);
$tmpFile = $this->getTemporaryFile($options['temp_dir']);

try {
$image->save($tmpFile, $this->getImagineSaveOptions($options));
$image = $this->imagine->open($tmpFile);
$this->delTemporaryFile($tmpFile);
} catch (\Exception $exception) {
$this->delTemporaryFile($tmpFile);
throw new LoadFilterException('Unable to save/open file in resample filter loader.', null, $exception);
}

return $image;
}

/**
* @param string $path
*
* @throws \RuntimeException
*
* @return string
*/
private function getTemporaryFile($path)
{
if (!is_dir($path) || false === $file = tempnam($path, 'liip-imagine-bundle')) {
throw new \RuntimeException(sprintf('Unable to create temporary file in "%s" base path.', $path));
}

return $file;
}

/**
* @param $file
*
* @throws \RuntimeException
*/
private function delTemporaryFile($file)
{
if (file_exists($file)) {
unlink($file);
}
}

/**
* @param array $options
*
* @return array
*/
private function getImagineSaveOptions(array $options)
{
$saveOptions = array(
'resolution-units' => $options['unit'],
'resolution-x' => $options['x'],
'resolution-y' => $options['y'],
);

if (isset($options['filter'])) {
$saveOptions['resampling-filter'] = $options['filter'];
}

return $saveOptions;
}

/**
* @param array $options
*
* @return array
*/
private function resolveOptions(array $options)
{
$resolver = new OptionsResolver();
$resolver->setDefined(array('filter'));
$resolver->setRequired(array('x', 'y', 'unit', 'temp_dir'));

$resolver->setDefault('temp_dir', sys_get_temp_dir());
$resolver->setAllowedTypes('temp_dir', array('string'));
$resolver->setAllowedTypes('x', array('int'));
$resolver->setAllowedTypes('y', array('int'));

$resolver->setAllowedValues('unit', array('inch', 'centimeter'));
$resolver->setNormalizer('unit', function (Options $options, $value) {
return $this->normalizeOptionUnit($value);
});

$resolver->setDefault('filter', 'UNDEFINED');
$resolver->setAllowedTypes('filter', array('string'));
$resolver->setNormalizer('filter', function (Options $options, $value) {
return $this->normalizeOptionFilter($value);
});

try {
return $resolver->resolve($options);
} catch (ExceptionInterface $e) {
throw new InvalidArgumentException('Invalid options provided. The "units" option must be set to "inch" '.
'or "centimeter" and you must set a "x" and "y" value to the ppi/ppc desired.');
}
}

/**
* @param string $value
*
* @return string
*/
private function normalizeOptionUnit($value)
{
return $value === 'inch' ? ImageInterface::RESOLUTION_PIXELSPERINCH : ImageInterface::RESOLUTION_PIXELSPERCENTIMETER;
}

/**
* @param string $value
*
* @return string
*/
private function normalizeOptionFilter($value)
{
foreach (array('\Imagine\Image\ImageInterface::FILTER_%s', '\Imagine\Image\ImageInterface::%s', '\%s') as $format) {
if (defined($constant = sprintf($format, strtoupper($value)))) {
return constant($constant);
}
}

throw new InvalidArgumentException('The "filter" option must resolve to a valid constant using one of the '.
'following formats: "\Imagine\Image\ImageInterface::FILTER_%s" or "\Imagine\Image\ImageInterface::%s" '.
'or "\%s"');
}
}
6 changes: 6 additions & 0 deletions Resources/config/imagine.xml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
<parameter key="liip_imagine.filter.loader.rotate.class">Liip\ImagineBundle\Imagine\Filter\Loader\RotateFilterLoader</parameter>
<parameter key="liip_imagine.filter.loader.flip.class">Liip\ImagineBundle\Imagine\Filter\Loader\FlipFilterLoader</parameter>
<parameter key="liip_imagine.filter.loader.interlace.class">Liip\ImagineBundle\Imagine\Filter\Loader\InterlaceFilterLoader</parameter>
<parameter key="liip_imagine.filter.loader.resample.class">Liip\ImagineBundle\Imagine\Filter\Loader\ResampleFilterLoader</parameter>

<!-- Data loaders' classes -->

Expand Down Expand Up @@ -230,6 +231,11 @@
<tag name="liip_imagine.filter.loader" loader="interlace" />
</service>

<service id="liip_imagine.filter.loader.resample" class="%liip_imagine.filter.loader.resample.class%">
<argument type="service" id="liip_imagine" />
<tag name="liip_imagine.filter.loader" loader="resample" />
</service>

<!-- Data loaders -->

<service id="liip_imagine.binary.loader.prototype.filesystem" class="%liip_imagine.binary.loader.filesystem.class%">
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

/*
* This file is part of the `liip/LiipImagineBundle` project.
*
* (c) https://github.com/liip/LiipImagineBundle/graphs/contributors
*
* For the full copyright and license information, please view the LICENSE.md
* file that was distributed with this source code.
*/

namespace Liip\ImagineBundle\Tests\Functional\Imagine\Filter\Loader;

use Liip\ImagineBundle\Tests\Functional\AbstractWebTestCase;

/**
* @covers \Liip\ImagineBundle\Imagine\Filter\Loader\ResampleFilterLoader
*/
class ResampleFilterLoaderTest extends AbstractWebTestCase
{
public function testContainerHasService()
{
$this->createClient();

$this->assertInstanceOf(
'\Liip\ImagineBundle\Imagine\Filter\Loader\ResampleFilterLoader',
self::$kernel->getContainer()->get('liip_imagine.filter.loader.resample')
);
}
}
Loading

0 comments on commit 1d71c29

Please sign in to comment.