1
0
mirror of https://github.com/Intervention/image.git synced 2025-08-11 16:34:00 +02:00

Add remove animation modifiers

This commit is contained in:
Oliver Vogel
2023-09-30 17:00:22 +02:00
parent 7577986980
commit 635567e9c2
7 changed files with 137 additions and 5 deletions

View File

@@ -334,6 +334,13 @@ abstract class AbstractImage implements ImageInterface
); );
} }
public function removeAnimation(int $position = 0): ImageInterface
{
return $this->modify(
$this->resolveDriverClass('Modifiers\RemoveAnimationModifier', $position)
);
}
public function destroy(): void public function destroy(): void
{ {
$this->modify( $this->modify(

View File

@@ -0,0 +1,35 @@
<?php
namespace Intervention\Image\Drivers\Gd\Modifiers;
use Intervention\Image\Collection;
use Intervention\Image\Drivers\Gd\Image;
use Intervention\Image\Exceptions\RuntimeException;
use Intervention\Image\Interfaces\ImageInterface;
use Intervention\Image\Interfaces\ModifierInterface;
class RemoveAnimationModifier implements ModifierInterface
{
public function __construct(protected int $position = 0)
{
//
}
public function apply(ImageInterface $image): ImageInterface
{
if (!$image->isAnimated()) {
throw new RuntimeException('Image is not animated.');
}
$frames = new Collection();
foreach ($image as $key => $frame) {
if ($this->position == $key) {
$frames->push($frame);
} else {
imagedestroy($frame->getCore());
}
}
return new Image($frames);
}
}

View File

@@ -26,13 +26,13 @@ class Image extends AbstractImage implements ImageInterface, Iterator
public function getFrame(int $position = 0): ?FrameInterface public function getFrame(int $position = 0): ?FrameInterface
{ {
try { foreach ($this->imagick as $core) {
$this->imagick->setIteratorIndex($position); if ($core->getIteratorIndex() == $position) {
} catch (ImagickException $e) { return new Frame($core);
return null; }
} }
return new Frame($this->imagick->current()); return null;
} }
public function addFrame(FrameInterface $frame): ImageInterface public function addFrame(FrameInterface $frame): ImageInterface

View File

@@ -0,0 +1,35 @@
<?php
namespace Intervention\Image\Drivers\Imagick\Modifiers;
use Imagick;
use Intervention\Image\Drivers\Imagick\Image;
use Intervention\Image\Exceptions\RuntimeException;
use Intervention\Image\Interfaces\ImageInterface;
use Intervention\Image\Interfaces\ModifierInterface;
class RemoveAnimationModifier implements ModifierInterface
{
public function __construct(protected int $position = 0)
{
//
}
public function apply(ImageInterface $image): ImageInterface
{
if (!$image->isAnimated()) {
throw new RuntimeException('Image is not animated.');
}
$imagick = new Imagick();
foreach ($image as $frame) {
if ($frame->getCore()->getIteratorIndex() == $this->position) {
$imagick->addImage($frame->getCore()->getImage());
}
}
$image->destroy();
return new Image($imagick);
}
}

View File

@@ -62,6 +62,13 @@ interface ImageInterface extends Traversable, Countable
*/ */
public function isAnimated(): bool; public function isAnimated(): bool;
/**
* Remove all frames but keep the one at the specified position
*
* @param int $position
* @return ImageInterface
*/
public function removeAnimation(int $position = 0): ImageInterface;
/** /**
* Apply given modifier to current image * Apply given modifier to current image

View File

@@ -0,0 +1,24 @@
<?php
namespace Intervention\Image\Tests\Drivers\Gd\Modifiers;
use Intervention\Image\Drivers\Gd\Modifiers\RemoveAnimationModifier;
use Intervention\Image\Tests\TestCase;
use Intervention\Image\Tests\Traits\CanCreateGdTestImage;
/**
* @requires extension gd
* @covers \Intervention\Image\Drivers\Gd\Modifiers\RemoveAnimationModifier
*/
class RemoveAnimationModifierTest extends TestCase
{
use CanCreateGdTestImage;
public function testApply(): void
{
$image = $this->createTestImage('animation.gif');
$this->assertEquals(8, count($image));
$image = $image->modify(new RemoveAnimationModifier(2));
$this->assertEquals(1, count($image));
}
}

View File

@@ -0,0 +1,24 @@
<?php
namespace Intervention\Image\Tests\Drivers\Imagick\Modifiers;
use Intervention\Image\Drivers\Imagick\Modifiers\RemoveAnimationModifier;
use Intervention\Image\Tests\TestCase;
use Intervention\Image\Tests\Traits\CanCreateImagickTestImage;
/**
* @requires extension imagick
* @covers \Intervention\Image\Drivers\Imagick\Modifiers\RemoveAnimationModifier
*/
class RemoveAnimationModifierTest extends TestCase
{
use CanCreateImagickTestImage;
public function testApply(): void
{
$image = $this->createTestImage('animation.gif');
$this->assertEquals(8, count($image));
$image = $image->modify(new RemoveAnimationModifier(2));
$this->assertEquals(1, count($image));
}
}