Skip to content

Commit

Permalink
Add remove animation modifiers
Browse files Browse the repository at this point in the history
  • Loading branch information
olivervogel committed Sep 30, 2023
1 parent 7577986 commit 635567e
Show file tree
Hide file tree
Showing 7 changed files with 137 additions and 5 deletions.
7 changes: 7 additions & 0 deletions src/Drivers/Abstract/AbstractImage.php
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,13 @@ public function padDown(
);
}

public function removeAnimation(int $position = 0): ImageInterface
{
return $this->modify(
$this->resolveDriverClass('Modifiers\RemoveAnimationModifier', $position)
);
}

public function destroy(): void
{
$this->modify(
Expand Down
35 changes: 35 additions & 0 deletions src/Drivers/Gd/Modifiers/RemoveAnimationModifier.php
Original file line number Diff line number Diff line change
@@ -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);
}
}
10 changes: 5 additions & 5 deletions src/Drivers/Imagick/Image.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,13 @@ public function getImagick(): Imagick

public function getFrame(int $position = 0): ?FrameInterface
{
try {
$this->imagick->setIteratorIndex($position);
} catch (ImagickException $e) {
return null;
foreach ($this->imagick as $core) {
if ($core->getIteratorIndex() == $position) {
return new Frame($core);
}
}

return new Frame($this->imagick->current());
return null;
}

public function addFrame(FrameInterface $frame): ImageInterface
Expand Down
35 changes: 35 additions & 0 deletions src/Drivers/Imagick/Modifiers/RemoveAnimationModifier.php
Original file line number Diff line number Diff line change
@@ -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);
}
}
7 changes: 7 additions & 0 deletions src/Interfaces/ImageInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,13 @@ public function getSize(): SizeInterface;
*/
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
Expand Down
24 changes: 24 additions & 0 deletions tests/Drivers/Gd/Modifiers/RemoveAnimationModifierTest.php
Original file line number Diff line number Diff line change
@@ -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));
}
}
24 changes: 24 additions & 0 deletions tests/Drivers/Imagick/Modifiers/RemoveAnimationModifierTest.php
Original file line number Diff line number Diff line change
@@ -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));
}
}

0 comments on commit 635567e

Please sign in to comment.