mirror of
https://github.com/Intervention/image.git
synced 2025-08-07 14:26:31 +02:00
Add percent values as input for ImageInterface::removeAnimation()
This commit is contained in:
@@ -374,7 +374,7 @@ abstract class AbstractImage implements ImageInterface
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function removeAnimation(int $position = 0): ImageInterface
|
public function removeAnimation(int|string $position = 0): ImageInterface
|
||||||
{
|
{
|
||||||
return $this->modify(
|
return $this->modify(
|
||||||
$this->resolveDriverClass('Modifiers\RemoveAnimationModifier', $position)
|
$this->resolveDriverClass('Modifiers\RemoveAnimationModifier', $position)
|
||||||
|
@@ -0,0 +1,29 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Intervention\Image\Drivers\Abstract\Modifiers;
|
||||||
|
|
||||||
|
use Intervention\Image\Exceptions\InputException;
|
||||||
|
use Intervention\Image\Interfaces\FrameInterface;
|
||||||
|
use Intervention\Image\Interfaces\ModifierInterface;
|
||||||
|
|
||||||
|
abstract class AbstractRemoveAnimationModifier implements ModifierInterface
|
||||||
|
{
|
||||||
|
protected function chosenFrame($image, int|string $position): FrameInterface
|
||||||
|
{
|
||||||
|
if (is_int($position)) {
|
||||||
|
return $image->frame($position);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (preg_match("/^(?P<percent>[0-9]{1,3})%$/", $position, $matches) != 1) {
|
||||||
|
throw new InputException(
|
||||||
|
'Input value of Image::removeAnimation() must be either integer or a percent value as string.'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$total = count($image);
|
||||||
|
$position = intval(round($total / 100 * intval($matches['percent'])));
|
||||||
|
$position = $position == $total ? $position - 1 : $position;
|
||||||
|
|
||||||
|
return $image->frame($position);
|
||||||
|
}
|
||||||
|
}
|
@@ -3,36 +3,25 @@
|
|||||||
namespace Intervention\Image\Drivers\Gd\Modifiers;
|
namespace Intervention\Image\Drivers\Gd\Modifiers;
|
||||||
|
|
||||||
use Intervention\Image\Collection;
|
use Intervention\Image\Collection;
|
||||||
use Intervention\Image\Drivers\Gd\Image;
|
use Intervention\Image\Drivers\Abstract\Modifiers\AbstractRemoveAnimationModifier;
|
||||||
use Intervention\Image\Exceptions\RuntimeException;
|
|
||||||
use Intervention\Image\Interfaces\ImageInterface;
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
use Intervention\Image\Interfaces\ModifierInterface;
|
|
||||||
use Intervention\Image\Traits\CanCheckType;
|
use Intervention\Image\Traits\CanCheckType;
|
||||||
|
use Intervention\Image\Drivers\Gd\Image;
|
||||||
|
|
||||||
class RemoveAnimationModifier implements ModifierInterface
|
class RemoveAnimationModifier extends AbstractRemoveAnimationModifier
|
||||||
{
|
{
|
||||||
use CanCheckType;
|
use CanCheckType;
|
||||||
|
|
||||||
public function __construct(protected int $position = 0)
|
public function __construct(protected int|string $position = 0)
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
|
|
||||||
public function apply(ImageInterface $image): ImageInterface
|
public function apply(ImageInterface $image): ImageInterface
|
||||||
{
|
{
|
||||||
if (!$image->isAnimated()) {
|
|
||||||
throw new RuntimeException('Image is not animated.');
|
|
||||||
}
|
|
||||||
|
|
||||||
$image = $this->failIfNotClass($image, Image::class);
|
$image = $this->failIfNotClass($image, Image::class);
|
||||||
|
return $image->setFrames(new Collection([
|
||||||
$frames = new Collection();
|
$this->chosenFrame($image, $this->position)
|
||||||
foreach ($image as $key => $frame) {
|
]));
|
||||||
if ($this->position == $key) {
|
|
||||||
$frames->push($frame);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $image->setFrames($frames);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -3,36 +3,28 @@
|
|||||||
namespace Intervention\Image\Drivers\Imagick\Modifiers;
|
namespace Intervention\Image\Drivers\Imagick\Modifiers;
|
||||||
|
|
||||||
use Imagick;
|
use Imagick;
|
||||||
use Intervention\Image\Exceptions\RuntimeException;
|
use Intervention\Image\Drivers\Abstract\Modifiers\AbstractRemoveAnimationModifier;
|
||||||
use Intervention\Image\Interfaces\ImageInterface;
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
use Intervention\Image\Interfaces\ModifierInterface;
|
|
||||||
use Intervention\Image\Drivers\Imagick\Image;
|
use Intervention\Image\Drivers\Imagick\Image;
|
||||||
use Intervention\Image\Traits\CanCheckType;
|
use Intervention\Image\Traits\CanCheckType;
|
||||||
|
|
||||||
class RemoveAnimationModifier implements ModifierInterface
|
class RemoveAnimationModifier extends AbstractRemoveAnimationModifier
|
||||||
{
|
{
|
||||||
use CanCheckType;
|
use CanCheckType;
|
||||||
|
|
||||||
public function __construct(protected int $position = 0)
|
public function __construct(protected int|string $position = 0)
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
|
|
||||||
public function apply(ImageInterface $image): ImageInterface
|
public function apply(ImageInterface $image): ImageInterface
|
||||||
{
|
{
|
||||||
if (!$image->isAnimated()) {
|
|
||||||
throw new RuntimeException('Image is not animated.');
|
|
||||||
}
|
|
||||||
|
|
||||||
$image = $this->failIfNotClass($image, Image::class);
|
$image = $this->failIfNotClass($image, Image::class);
|
||||||
|
|
||||||
// create new imagick with just one image
|
// create new imagick with just one image
|
||||||
$imagick = new Imagick();
|
$imagick = new Imagick();
|
||||||
foreach ($image->getImagick() as $key => $core) {
|
$frame = $this->chosenFrame($image, $this->position);
|
||||||
if ($key == $this->position) {
|
$imagick->addImage($frame->core()->getImage());
|
||||||
$imagick->addImage($core->getImage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $image->setImagick($imagick);
|
return $image->setImagick($imagick);
|
||||||
}
|
}
|
||||||
|
8
src/Exceptions/InputException.php
Normal file
8
src/Exceptions/InputException.php
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Intervention\Image\Exceptions;
|
||||||
|
|
||||||
|
class InputException extends \RuntimeException
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
@@ -79,10 +79,10 @@ interface ImageInterface extends Traversable, Countable
|
|||||||
/**
|
/**
|
||||||
* Remove all frames but keep the one at the specified position
|
* Remove all frames but keep the one at the specified position
|
||||||
*
|
*
|
||||||
* @param int $position
|
* @param int|string $position
|
||||||
* @return ImageInterface
|
* @return ImageInterface
|
||||||
*/
|
*/
|
||||||
public function removeAnimation(int $position = 0): ImageInterface;
|
public function removeAnimation(int|string $position = 0): ImageInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Apply given modifier to current image
|
* Apply given modifier to current image
|
||||||
|
@@ -22,4 +22,13 @@ class RemoveAnimationModifierTest extends TestCase
|
|||||||
$this->assertEquals(1, count($image));
|
$this->assertEquals(1, count($image));
|
||||||
$this->assertEquals(1, count($result));
|
$this->assertEquals(1, count($result));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testApplyPercent(): void
|
||||||
|
{
|
||||||
|
$image = $this->createTestImage('animation.gif');
|
||||||
|
$this->assertEquals(8, count($image));
|
||||||
|
$result = $image->modify(new RemoveAnimationModifier('20%'));
|
||||||
|
$this->assertEquals(1, count($image));
|
||||||
|
$this->assertEquals(1, count($result));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -22,4 +22,13 @@ class RemoveAnimationModifierTest extends TestCase
|
|||||||
$this->assertEquals(1, count($image));
|
$this->assertEquals(1, count($image));
|
||||||
$this->assertEquals(1, count($result));
|
$this->assertEquals(1, count($result));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testApplyPercent(): void
|
||||||
|
{
|
||||||
|
$image = $this->createTestImage('animation.gif');
|
||||||
|
$this->assertEquals(8, count($image));
|
||||||
|
$result = $image->modify(new RemoveAnimationModifier('20%'));
|
||||||
|
$this->assertEquals(1, count($image));
|
||||||
|
$this->assertEquals(1, count($result));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user