From 90ed724cb582598cad3fdcb2a37a2750e9ac846c Mon Sep 17 00:00:00 2001 From: Oliver Vogel Date: Mon, 20 Jun 2022 16:33:38 +0200 Subject: [PATCH] Refactor storage of Imagick core, remove method Imagick core image was disassembled in the decoding process. This made the whole object not very memory efficient. This fixes the issue by keeping the original Imagick object in the Intervention Image object. Also the Image::getFrames() method was removed. Users should use iteration to access frames. --- src/Collection.php | 5 +- src/Drivers/Abstract/AbstractImage.php | 47 +------- src/Drivers/Gd/Encoders/GifEncoder.php | 2 +- src/Drivers/Gd/Encoders/JpegEncoder.php | 2 +- src/Drivers/Gd/Encoders/PngEncoder.php | 2 +- src/Drivers/Gd/Encoders/WebpEncoder.php | 2 +- src/Drivers/Gd/Image.php | 47 ++++++++ .../Imagick/Decoders/BinaryImageDecoder.php | 10 +- src/Drivers/Imagick/Encoders/GifEncoder.php | 2 +- src/Drivers/Imagick/Encoders/JpegEncoder.php | 2 +- src/Drivers/Imagick/Encoders/PngEncoder.php | 2 +- src/Drivers/Imagick/Encoders/WebpEncoder.php | 2 +- src/Drivers/Imagick/Frame.php | 3 +- src/Drivers/Imagick/Image.php | 109 +++++++++++++++++- src/Drivers/Imagick/ImageFactory.php | 8 +- src/Interfaces/CollectionInterface.php | 4 +- src/Interfaces/ImageInterface.php | 6 +- tests/Drivers/Abstract/AbstractImageTest.php | 58 +--------- tests/Drivers/Gd/ImageTest.php | 16 +-- .../Imagick/Encoders/GifEncoderTest.php | 30 ++--- .../Imagick/Encoders/JpegEncoderTest.php | 5 +- .../Imagick/Encoders/PngEncoderTest.php | 5 +- .../Imagick/Encoders/WebpEncoderTest.php | 5 +- tests/Drivers/Imagick/ImageTest.php | 41 ++++++- 24 files changed, 241 insertions(+), 174 deletions(-) diff --git a/src/Collection.php b/src/Collection.php index e1e37a6c..5434f83b 100644 --- a/src/Collection.php +++ b/src/Collection.php @@ -6,6 +6,7 @@ use Intervention\Image\Exceptions\RuntimeException; use Intervention\Image\Interfaces\CollectionInterface; use ArrayIterator; use Countable; +use Traversable; use IteratorAggregate; use RecursiveIteratorIterator; use RecursiveArrayIterator; @@ -31,9 +32,9 @@ class Collection implements CollectionInterface, IteratorAggregate, Countable /** * Returns Iterator * - * @return \Traversable + * @return Traversable */ - public function getIterator(): \Traversable + public function getIterator(): Traversable { return new ArrayIterator($this->items); } diff --git a/src/Drivers/Abstract/AbstractImage.php b/src/Drivers/Abstract/AbstractImage.php index 530e5291..29fd8f0a 100644 --- a/src/Drivers/Abstract/AbstractImage.php +++ b/src/Drivers/Abstract/AbstractImage.php @@ -8,7 +8,6 @@ use Intervention\Image\Geometry\Point; use Intervention\Image\Geometry\Size; use Intervention\Image\Interfaces\CollectionInterface; use Intervention\Image\Interfaces\EncoderInterface; -use Intervention\Image\Interfaces\FrameInterface; use Intervention\Image\Interfaces\ImageInterface; use Intervention\Image\Interfaces\ModifierInterface; use Intervention\Image\Interfaces\SizeInterface; @@ -20,45 +19,6 @@ abstract class AbstractImage implements ImageInterface use CanResolveDriverClass; use CanHandleInput; - public function __construct(protected Collection $frames, protected $loops = 0) - { - // - } - - public function getIterator(): CollectionInterface - { - return $this->frames; - } - - public function getFrames(): CollectionInterface - { - return $this->frames; - } - - public function getFrame(int $key = 0): ?FrameInterface - { - return $this->frames->get($key); - } - - public function addFrame(FrameInterface $frame): ImageInterface - { - $this->frames->push($frame); - - return $this; - } - - public function setLoops(int $count): ImageInterface - { - $this->loops = $count; - - return $this; - } - - public function getLoops(): int - { - return $this->loops; - } - public function getSize(): SizeInterface { return new Size($this->getWidth(), $this->getHeight()); @@ -69,11 +29,6 @@ abstract class AbstractImage implements ImageInterface return $this->getSize(); } - public function isAnimated(): bool - { - return $this->getFrames()->count() > 1; - } - public function modify(ModifierInterface $modifier): ImageInterface { return $modifier->apply($this); @@ -229,7 +184,7 @@ abstract class AbstractImage implements ImageInterface public function pickColors(int $x, int $y): CollectionInterface { $colors = new Collection(); - foreach ($this->getFrames() as $key => $frame) { + foreach ($this as $key => $frame) { $colors->push($this->pickColor($x, $y, $key)); } diff --git a/src/Drivers/Gd/Encoders/GifEncoder.php b/src/Drivers/Gd/Encoders/GifEncoder.php index 31227a15..159cc2cd 100644 --- a/src/Drivers/Gd/Encoders/GifEncoder.php +++ b/src/Drivers/Gd/Encoders/GifEncoder.php @@ -17,7 +17,7 @@ class GifEncoder extends AbstractEncoder implements EncoderInterface } $data = $this->getBuffered(function () use ($image) { - imagegif($image->getFrames()->first()->getCore()); + imagegif($image->getFrame()->getCore()); }); return new EncodedImage($data, 'image/gif'); diff --git a/src/Drivers/Gd/Encoders/JpegEncoder.php b/src/Drivers/Gd/Encoders/JpegEncoder.php index 09e695e7..2a8d41da 100644 --- a/src/Drivers/Gd/Encoders/JpegEncoder.php +++ b/src/Drivers/Gd/Encoders/JpegEncoder.php @@ -17,7 +17,7 @@ class JpegEncoder extends AbstractEncoder implements EncoderInterface public function encode(ImageInterface $image): EncodedImage { $data = $this->getBuffered(function () use ($image) { - imagejpeg($image->getFrames()->first()->getCore(), null, $this->quality); + imagejpeg($image->getFrame()->getCore(), null, $this->quality); }); return new EncodedImage($data, 'image/jpeg'); diff --git a/src/Drivers/Gd/Encoders/PngEncoder.php b/src/Drivers/Gd/Encoders/PngEncoder.php index bc578b47..4369ef14 100644 --- a/src/Drivers/Gd/Encoders/PngEncoder.php +++ b/src/Drivers/Gd/Encoders/PngEncoder.php @@ -12,7 +12,7 @@ class PngEncoder extends AbstractEncoder implements EncoderInterface public function encode(ImageInterface $image): EncodedImage { $data = $this->getBuffered(function () use ($image) { - imagepng($image->getFrames()->first()->getCore(), null, -1); + imagepng($image->getFrame()->getCore(), null, -1); }); return new EncodedImage($data, 'image/png'); diff --git a/src/Drivers/Gd/Encoders/WebpEncoder.php b/src/Drivers/Gd/Encoders/WebpEncoder.php index 748db2a2..581358f0 100644 --- a/src/Drivers/Gd/Encoders/WebpEncoder.php +++ b/src/Drivers/Gd/Encoders/WebpEncoder.php @@ -17,7 +17,7 @@ class WebpEncoder extends AbstractEncoder implements EncoderInterface public function encode(ImageInterface $image): EncodedImage { $data = $this->getBuffered(function () use ($image) { - imagewebp($image->getFrames()->first()->getCore(), null, $this->quality); + imagewebp($image->getFrame()->getCore(), null, $this->quality); }); return new EncodedImage($data, 'image/webp'); diff --git a/src/Drivers/Gd/Image.php b/src/Drivers/Gd/Image.php index 38c42981..fdacd9d7 100644 --- a/src/Drivers/Gd/Image.php +++ b/src/Drivers/Gd/Image.php @@ -2,13 +2,60 @@ namespace Intervention\Image\Drivers\Gd; +use Intervention\Image\Collection; use Intervention\Image\Drivers\Abstract\AbstractImage; use Intervention\Image\Interfaces\ColorInterface; +use Intervention\Image\Interfaces\FrameInterface; use Intervention\Image\Interfaces\ImageInterface; use IteratorAggregate; +use Traversable; class Image extends AbstractImage implements ImageInterface, IteratorAggregate { + public function __construct(protected Collection $frames, protected int $loops = 0) + { + // + } + + public function getIterator(): Traversable + { + return $this->frames; + } + + public function count(): int + { + return $this->frames->count(); + } + + public function isAnimated(): bool + { + return $this->count() > 1; + } + + public function getLoops(): int + { + return $this->loops; + } + + public function setLoops(int $count): self + { + $this->loops = $count; + + return $this; + } + + public function getFrame(int $key = 0): ?FrameInterface + { + return $this->frames->get($key); + } + + public function addFrame(FrameInterface $frame): ImageInterface + { + $this->frames->push($frame); + + return $this; + } + public function getWidth(): int { return imagesx($this->getFrame()->getCore()); diff --git a/src/Drivers/Imagick/Decoders/BinaryImageDecoder.php b/src/Drivers/Imagick/Decoders/BinaryImageDecoder.php index 7a8b4e02..5cb31596 100644 --- a/src/Drivers/Imagick/Decoders/BinaryImageDecoder.php +++ b/src/Drivers/Imagick/Decoders/BinaryImageDecoder.php @@ -3,9 +3,7 @@ namespace Intervention\Image\Drivers\Imagick\Decoders; use Imagick; -use Intervention\Image\Collection; use Intervention\Image\Drivers\Abstract\Decoders\AbstractDecoder; -use Intervention\Image\Drivers\Imagick\Frame; use Intervention\Image\Drivers\Imagick\Image; use Intervention\Image\Exceptions\DecoderException; use Intervention\Image\Interfaces\ColorInterface; @@ -28,15 +26,9 @@ class BinaryImageDecoder extends AbstractDecoder implements DecoderInterface $imagick->readImageBlob($input); $imagick = $imagick->coalesceImages(); - $image = new Image(new Collection()); + $image = new Image($imagick); $image->setLoops($imagick->getImageIterations()); - foreach ($imagick as $frame_content) { - $image->addFrame( - new Frame($frame_content->getImage()) - ); - } - return $image; } } diff --git a/src/Drivers/Imagick/Encoders/GifEncoder.php b/src/Drivers/Imagick/Encoders/GifEncoder.php index 0cfca898..7524380b 100644 --- a/src/Drivers/Imagick/Encoders/GifEncoder.php +++ b/src/Drivers/Imagick/Encoders/GifEncoder.php @@ -16,7 +16,7 @@ class GifEncoder extends AbstractEncoder implements EncoderInterface $compression = Imagick::COMPRESSION_LZW; $gif = new Imagick() ; - foreach ($image->getFrames() as $frame) { + foreach ($image as $frame) { $gif->addImage($frame->getCore()); } diff --git a/src/Drivers/Imagick/Encoders/JpegEncoder.php b/src/Drivers/Imagick/Encoders/JpegEncoder.php index 0ea13e67..c6191704 100644 --- a/src/Drivers/Imagick/Encoders/JpegEncoder.php +++ b/src/Drivers/Imagick/Encoders/JpegEncoder.php @@ -20,7 +20,7 @@ class JpegEncoder extends AbstractEncoder implements EncoderInterface $format = 'jpeg'; $compression = Imagick::COMPRESSION_JPEG; - $imagick = $image->getFrames()->first()->getCore(); + $imagick = $image->getFrame()->getCore(); $imagick->setImageBackgroundColor('white'); $imagick->setBackgroundColor('white'); $imagick->setFormat($format); diff --git a/src/Drivers/Imagick/Encoders/PngEncoder.php b/src/Drivers/Imagick/Encoders/PngEncoder.php index 8bdc03e6..3599c02e 100644 --- a/src/Drivers/Imagick/Encoders/PngEncoder.php +++ b/src/Drivers/Imagick/Encoders/PngEncoder.php @@ -15,7 +15,7 @@ class PngEncoder extends AbstractEncoder implements EncoderInterface $format = 'png'; $compression = Imagick::COMPRESSION_ZIP; - $imagick = $image->getFrames()->first()->getCore(); + $imagick = $image->getFrame()->getCore(); $imagick->setFormat($format); $imagick->setImageFormat($format); $imagick->setCompression($compression); diff --git a/src/Drivers/Imagick/Encoders/WebpEncoder.php b/src/Drivers/Imagick/Encoders/WebpEncoder.php index 0f7cb9f9..3f445233 100644 --- a/src/Drivers/Imagick/Encoders/WebpEncoder.php +++ b/src/Drivers/Imagick/Encoders/WebpEncoder.php @@ -21,7 +21,7 @@ class WebpEncoder extends AbstractEncoder implements EncoderInterface $format = 'webp'; $compression = Imagick::COMPRESSION_ZIP; - $imagick = $image->getFrames()->first()->getCore(); + $imagick = $image->getFrame()->getCore(); $imagick->setImageBackgroundColor(new ImagickPixel('transparent')); $imagick = $imagick->mergeImageLayers(Imagick::LAYERMETHOD_MERGE); diff --git a/src/Drivers/Imagick/Frame.php b/src/Drivers/Imagick/Frame.php index ef4bd57b..cb49b24d 100644 --- a/src/Drivers/Imagick/Frame.php +++ b/src/Drivers/Imagick/Frame.php @@ -3,7 +3,6 @@ namespace Intervention\Image\Drivers\Imagick; use Imagick; -use Intervention\Image\Collection; use Intervention\Image\Geometry\Size; use Intervention\Image\Interfaces\FrameInterface; use Intervention\Image\Interfaces\ImageInterface; @@ -91,6 +90,6 @@ class Frame implements FrameInterface public function toImage(): ImageInterface { - return new Image(new Collection([$this])); + return new Image($this->getCore()); } } diff --git a/src/Drivers/Imagick/Image.php b/src/Drivers/Imagick/Image.php index f6507eec..e41886c9 100644 --- a/src/Drivers/Imagick/Image.php +++ b/src/Drivers/Imagick/Image.php @@ -2,21 +2,122 @@ namespace Intervention\Image\Drivers\Imagick; +use Imagick; +use ImagickException; use Intervention\Image\Drivers\Abstract\AbstractImage; use Intervention\Image\Interfaces\ColorInterface; +use Intervention\Image\Interfaces\FrameInterface; use Intervention\Image\Interfaces\ImageInterface; -use IteratorAggregate; +use Iterator; -class Image extends AbstractImage implements ImageInterface, IteratorAggregate +class Image extends AbstractImage implements ImageInterface, Iterator { + protected $iteratorIndex = 0; + + public function __construct(protected Imagick $core) + { + // + } + + public function getCore(): Imagick + { + return $this->core; + } + + public function getFrame(int $key = 0): ?FrameInterface + { + try { + $this->core->setIteratorIndex($key); + } catch (ImagickException $e) { + return null; + } + + return new Frame($this->core->current()); + } + + public function addFrame(FrameInterface $frame): ImageInterface + { + $imagick = $frame->getCore(); + + $imagick->setImageDelay($frame->getDelay()); + $imagick->setImageDispose($frame->getDispose()); + + $size = $frame->getSize(); + $imagick->setImagePage( + $size->getWidth(), + $size->getHeight(), + $frame->getOffsetLeft(), + $frame->getOffsetTop() + ); + + $this->core->addImage($imagick); + + return $this; + } + + public function setLoops(int $count): ImageInterface + { + $this->core->setImageIterations($count); + + return $this; + } + + public function getLoops(): int + { + return $this->core->getImageIterations(); + } + + public function isAnimated(): bool + { + return $this->count() > 1; + } + + public function count(): int + { + return $this->core->getNumberImages(); + } + + public function current() + { + $this->core->setIteratorIndex($this->iteratorIndex); + + return new Frame($this->core->current()); + } + + public function key() + { + return $this->iteratorIndex; + } + + public function next(): void + { + $this->iteratorIndex = $this->iteratorIndex + 1; + } + + public function rewind(): void + { + $this->iteratorIndex = 0; + } + + public function valid(): bool + { + try { + $result = $this->core->setIteratorIndex($this->iteratorIndex); + } catch (ImagickException $e) { + return false; + } + + return $result; + } + public function getWidth(): int { - return $this->frames->first()->getCore()->getImageWidth(); + return $this->getFrame()->getCore()->getImageWidth(); } public function getHeight(): int { - return $this->frames->first()->getCore()->getImageHeight(); + return $this->getFrame()->getCore()->getImageHeight(); } public function pickColor(int $x, int $y, int $frame_key = 0): ?ColorInterface diff --git a/src/Drivers/Imagick/ImageFactory.php b/src/Drivers/Imagick/ImageFactory.php index cff14438..57ef4cc3 100644 --- a/src/Drivers/Imagick/ImageFactory.php +++ b/src/Drivers/Imagick/ImageFactory.php @@ -4,8 +4,6 @@ namespace Intervention\Image\Drivers\Imagick; use Imagick; use ImagickPixel; -use Intervention\Image\Collection; -use Intervention\Image\Drivers\Imagick\Color; use Intervention\Image\Interfaces\FactoryInterface; use Intervention\Image\Interfaces\ImageInterface; @@ -13,11 +11,7 @@ class ImageFactory implements FactoryInterface { public function newImage(int $width, int $height): ImageInterface { - return new Image( - new Collection([ - new Frame($this->newCore($width, $height)) - ]) - ); + return new Image($this->newCore($width, $height)); } public function newCore(int $width, int $height): Imagick diff --git a/src/Interfaces/CollectionInterface.php b/src/Interfaces/CollectionInterface.php index fc87d626..9cfcbae3 100644 --- a/src/Interfaces/CollectionInterface.php +++ b/src/Interfaces/CollectionInterface.php @@ -2,7 +2,9 @@ namespace Intervention\Image\Interfaces; -interface CollectionInterface +use Traversable; + +interface CollectionInterface extends Traversable { public function push($item): CollectionInterface; public function get(int $key, $default = null); diff --git a/src/Interfaces/ImageInterface.php b/src/Interfaces/ImageInterface.php index 5f16c4d7..f69a9825 100644 --- a/src/Interfaces/ImageInterface.php +++ b/src/Interfaces/ImageInterface.php @@ -2,12 +2,12 @@ namespace Intervention\Image\Interfaces; +use Countable; use Intervention\Image\EncodedImage; +use Traversable; -interface ImageInterface +interface ImageInterface extends Traversable, Countable { - public function getIterator(): CollectionInterface; - public function getFrames(): CollectionInterface; public function getFrame(int $key = 0): ?FrameInterface; public function addFrame(FrameInterface $frame): ImageInterface; public function setLoops(int $count): ImageInterface; diff --git a/tests/Drivers/Abstract/AbstractImageTest.php b/tests/Drivers/Abstract/AbstractImageTest.php index 52581f21..dde2be23 100644 --- a/tests/Drivers/Abstract/AbstractImageTest.php +++ b/tests/Drivers/Abstract/AbstractImageTest.php @@ -30,58 +30,17 @@ class AbstractImageTest extends TestCase $collection = new Collection([$frame1, $frame2, $frame3]); - $mock = Mockery::mock(AbstractImage::class, ImageInterface::class, [$collection]) + $mock = Mockery::mock(AbstractImage::class, ImageInterface::class) ->shouldAllowMockingProtectedMethods() ->makePartial(); $mock->shouldReceive('getWidth')->andReturn(300); $mock->shouldReceive('getHeight')->andReturn(200); + $mock->shouldReceive('getIterator')->andReturn($collection); return $mock; } - public function testGetIterator(): void - { - $this->assertInstanceOf(Collection::class, $this->abstractImageMock()->getIterator()); - } - - public function testGetFrames(): void - { - $this->assertInstanceOf(Collection::class, $this->abstractImageMock()->getFrames()); - } - - public function testGetFrame(): void - { - $img = $this->abstractImageMock(); - - $this->assertInstanceOf(FrameInterface::class, $img->getFrame()); - $this->assertEquals(1, $img->getFrame()->ident()); - - $this->assertInstanceOf(FrameInterface::class, $img->getFrame(1)); - $this->assertEquals(2, $img->getFrame(1)->ident()); - - $this->assertInstanceOf(FrameInterface::class, $img->getFrame(2)); - $this->assertEquals(3, $img->getFrame(2)->ident()); - } - - public function testAddFrame(): void - { - $img = $this->abstractImageMock(); - $this->assertEquals(3, $img->getFrames()->count()); - $result = $img->addFrame(Mockery::mock(FrameInterface::class)); - $this->assertInstanceOf(AbstractImage::class, $result); - $this->assertEquals(4, $img->getFrames()->count()); - } - - public function testSetGetLoops(): void - { - $img = $this->abstractImageMock(); - $this->assertEquals(0, $img->getLoops()); - $result = $img->setLoops(10); - $this->assertEquals(10, $img->getLoops()); - $this->assertInstanceOf(AbstractImage::class, $result); - } - public function testGetSize(): void { $img = $this->abstractImageMock(); @@ -98,19 +57,6 @@ class AbstractImageTest extends TestCase $this->assertEquals(200, $img->size()->getHeight()); } - public function testIsAnimated(): void - { - $img = Mockery::mock(AbstractImage::class, [new Collection()])->makePartial(); - $this->assertFalse($img->isAnimated()); - - $collection = new Collection([ - Mockery::mock(FrameInterface::class), - Mockery::mock(FrameInterface::class), - ]); - $img = Mockery::mock(AbstractImage::class, [$collection])->makePartial(); - $this->assertTrue($img->isAnimated()); - } - public function testModify(): void { $img = $this->abstractImageMock(); diff --git a/tests/Drivers/Gd/ImageTest.php b/tests/Drivers/Gd/ImageTest.php index 82992c24..27ce28d1 100644 --- a/tests/Drivers/Gd/ImageTest.php +++ b/tests/Drivers/Gd/ImageTest.php @@ -37,6 +37,12 @@ class ImageTest extends TestCase $this->assertInstanceOf(Image::class, $this->image); } + public function testCount(): void + { + $this->assertEquals(3, $this->image->count()); + $this->assertEquals(3, count($this->image)); + } + public function testIterator(): void { foreach ($this->image as $frame) { @@ -44,12 +50,6 @@ class ImageTest extends TestCase } } - public function testGetFrames(): void - { - $this->assertInstanceOf(Collection::class, $this->image->getFrames()); - $this->assertCount(3, $this->image->getFrames()); - } - public function testGetFrame(): void { $this->assertInstanceOf(Frame::class, $this->image->getFrame()); @@ -58,10 +58,10 @@ class ImageTest extends TestCase public function testAddFrame(): void { - $this->assertCount(3, $this->image->getFrames()); + $this->assertCount(3, $this->image); $result = $this->image->addFrame(new Frame(imagecreatetruecolor(3, 2))); $this->assertInstanceOf(Image::class, $result); - $this->assertCount(4, $this->image->getFrames()); + $this->assertCount(4, $this->image); } public function testSetGetLoops(): void diff --git a/tests/Drivers/Imagick/Encoders/GifEncoderTest.php b/tests/Drivers/Imagick/Encoders/GifEncoderTest.php index f0624cf6..e12b631c 100644 --- a/tests/Drivers/Imagick/Encoders/GifEncoderTest.php +++ b/tests/Drivers/Imagick/Encoders/GifEncoderTest.php @@ -20,20 +20,24 @@ class GifEncoderTest extends TestCase { protected function getTestImage(): Image { - $imagick1 = new Imagick(); - $imagick1->newImage(30, 20, new ImagickPixel('red'), 'png'); - $frame1 = new Frame($imagick1); - $frame1->setDelay(50); - $imagick2 = new Imagick(); - $imagick2->newImage(30, 20, new ImagickPixel('green'), 'png'); - $frame2 = new Frame($imagick2); - $frame2->setDelay(50); - $imagick3 = new Imagick(); - $imagick3->newImage(30, 20, new ImagickPixel('blue'), 'png'); - $frame3 = new Frame($imagick3); - $frame3->setDelay(50); + $imagick = new Imagick(); - return new Image(new Collection([$frame1, $frame2, $frame3])); + $frame = new Imagick(); + $frame->newImage(30, 20, new ImagickPixel('red'), 'png'); + $frame->setImageDelay(50); + $imagick->addImage($frame); + + $frame = new Imagick(); + $frame->newImage(30, 20, new ImagickPixel('green'), 'png'); + $frame->setImageDelay(50); + $imagick->addImage($frame); + + $frame = new Imagick(); + $frame->newImage(30, 20, new ImagickPixel('blue'), 'png'); + $frame->setImageDelay(50); + $imagick->addImage($frame); + + return new Image($imagick); } public function testEncode(): void diff --git a/tests/Drivers/Imagick/Encoders/JpegEncoderTest.php b/tests/Drivers/Imagick/Encoders/JpegEncoderTest.php index 76ea3696..c5e7b702 100644 --- a/tests/Drivers/Imagick/Encoders/JpegEncoderTest.php +++ b/tests/Drivers/Imagick/Encoders/JpegEncoderTest.php @@ -4,9 +4,7 @@ namespace Intervention\Image\Tests\Drivers\Imagick\Encoders; use Imagick; use ImagickPixel; -use Intervention\Image\Collection; use Intervention\Image\Drivers\Imagick\Encoders\JpegEncoder; -use Intervention\Image\Drivers\Imagick\Frame; use Intervention\Image\Drivers\Imagick\Image; use Intervention\Image\Tests\TestCase; use Intervention\MimeSniffer\MimeSniffer; @@ -22,9 +20,8 @@ class JpegEncoderTest extends TestCase { $imagick = new Imagick(); $imagick->newImage(3, 2, new ImagickPixel('red'), 'png'); - $frame = new Frame($imagick); - return new Image(new Collection([$frame])); + return new Image($imagick); } public function testEncode(): void diff --git a/tests/Drivers/Imagick/Encoders/PngEncoderTest.php b/tests/Drivers/Imagick/Encoders/PngEncoderTest.php index 30b41fa8..92cf1fc6 100644 --- a/tests/Drivers/Imagick/Encoders/PngEncoderTest.php +++ b/tests/Drivers/Imagick/Encoders/PngEncoderTest.php @@ -6,9 +6,7 @@ namespace Intervention\Image\Tests\Drivers\Imagick\Encoders; use Imagick; use ImagickPixel; -use Intervention\Image\Collection; use Intervention\Image\Drivers\Imagick\Encoders\PngEncoder; -use Intervention\Image\Drivers\Imagick\Frame; use Intervention\Image\Drivers\Imagick\Image; use Intervention\MimeSniffer\MimeSniffer; use Intervention\MimeSniffer\Types\ImagePng; @@ -23,9 +21,8 @@ final class PngEncoderTest extends TestCase { $imagick = new Imagick(); $imagick->newImage(3, 2, new ImagickPixel('red'), 'jpg'); - $frame = new Frame($imagick); - return new Image(new Collection([$frame])); + return new Image($imagick); } public function testEncode(): void diff --git a/tests/Drivers/Imagick/Encoders/WebpEncoderTest.php b/tests/Drivers/Imagick/Encoders/WebpEncoderTest.php index dcced39b..69e9df2f 100644 --- a/tests/Drivers/Imagick/Encoders/WebpEncoderTest.php +++ b/tests/Drivers/Imagick/Encoders/WebpEncoderTest.php @@ -6,9 +6,7 @@ namespace Intervention\Image\Tests\Drivers\Imagick\Encoders; use Imagick; use ImagickPixel; -use Intervention\Image\Collection; use Intervention\Image\Drivers\Imagick\Encoders\WebpEncoder; -use Intervention\Image\Drivers\Imagick\Frame; use Intervention\Image\Drivers\Imagick\Image; use Intervention\MimeSniffer\MimeSniffer; use Intervention\MimeSniffer\Types\ImageWebp; @@ -23,9 +21,8 @@ final class WebpEncoderTest extends TestCase { $imagick = new Imagick(); $imagick->newImage(3, 2, new ImagickPixel('red'), 'png'); - $frame = new Frame($imagick); - return new Image(new Collection([$frame])); + return new Image($imagick); } public function testEncode(): void diff --git a/tests/Drivers/Imagick/ImageTest.php b/tests/Drivers/Imagick/ImageTest.php index 6337c1a7..53e38f2c 100644 --- a/tests/Drivers/Imagick/ImageTest.php +++ b/tests/Drivers/Imagick/ImageTest.php @@ -4,7 +4,6 @@ namespace Intervention\Image\Tests\Drivers\Imagick; use Imagick; use ImagickPixel; -use Intervention\Image\Collection; use Intervention\Image\Drivers\Imagick\Frame; use Intervention\Image\Drivers\Imagick\Image; use Intervention\Image\Geometry\Size; @@ -20,16 +19,46 @@ class ImageTest extends TestCase protected function setUp(): void { + // create base image $imagick = new Imagick(); - $imagick->newImage(3, 2, new ImagickPixel('red'), 'png'); - $this->image = new Image(new Collection([new Frame($imagick)])); + // add frame + $frame = new Imagick(); + $frame->newImage(3, 2, new ImagickPixel('red'), 'png'); + $imagick->addImage($frame); + + // add frame + $frame = new Imagick(); + $frame->newImage(3, 2, new ImagickPixel('green'), 'png'); + $imagick->addImage($frame); + + // create intervention image + $this->image = new Image($imagick); } public function testConstructor(): void { $this->assertInstanceOf(Image::class, $this->image); } + + public function testGetFrame(): void + { + $this->assertInstanceOf(Frame::class, $this->image->getFrame()); + $this->assertInstanceOf(Frame::class, $this->image->getFrame(1)); + $this->assertNull($this->image->getFrame(2)); + } + + public function testAddFrame(): void + { + $frame = new Imagick(); + $frame->newImage(3, 2, new ImagickPixel('blue'), 'png'); + $frame = new Frame($frame); + + $this->assertCount(2, $this->image); + $result = $this->image->addFrame($frame); + $this->assertInstanceOf(Image::class, $result); + $this->assertCount(3, $this->image); + } public function testIterator(): void { @@ -38,6 +67,12 @@ class ImageTest extends TestCase } } + public function testCount(): void + { + $this->assertEquals(2, $this->image->count()); + $this->assertEquals(2, count($this->image)); + } + public function testWidth(): void { $this->assertEquals(3, $this->image->getWidth());