1
0
mirror of https://github.com/Intervention/image.git synced 2025-01-18 04:38:26 +01:00

Merge branch 'next' into feature/text

This commit is contained in:
Oliver Vogel 2022-06-21 10:57:45 +02:00
commit de0182e386
26 changed files with 305 additions and 189 deletions

View File

@ -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);
}
@ -109,6 +110,11 @@ class Collection implements CollectionInterface, IteratorAggregate, Countable
return $this->items[$key];
}
public function has(int $key): bool
{
return array_key_exists($key, $this->items);
}
public function query(string $query, $default = null)
{
$items = $this->getItemsFlat();

View File

@ -6,8 +6,8 @@ use Intervention\Image\Collection;
use Intervention\Image\EncodedImage;
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 +20,6 @@ abstract class AbstractImage implements ImageInterface
use CanResolveDriverClass;
use CanHandleInput;
public function __construct(protected Collection $frames, protected $loops = 0)
{
//
}
public function getIterator(): Collection
{
return $this->frames;
}
public function getFrames(): Collection
{
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 +30,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);
@ -226,10 +182,10 @@ abstract class AbstractImage implements ImageInterface
);
}
public function pickColors(int $x, int $y): Collection
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));
}

View File

@ -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');

View File

@ -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');

View File

@ -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');

View File

@ -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');

View File

@ -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());

View File

@ -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;
}
}

View File

@ -15,18 +15,13 @@ class GifEncoder extends AbstractEncoder implements EncoderInterface
$format = 'gif';
$compression = Imagick::COMPRESSION_LZW;
$gif = new Imagick() ;
foreach ($image->getFrames() as $frame) {
$gif->addImage($frame->getCore());
}
$imagick = $image->getImagick();
$imagick->setFormat($format);
$imagick->setImageFormat($format);
$imagick->setCompression($compression);
$imagick->setImageCompression($compression);
$imagick = $imagick->deconstructImages();
$gif->setImageIterations($image->getLoops());
$gif->setFormat($format);
$gif->setImageFormat($format);
$gif->setCompression($compression);
$gif->setImageCompression($compression);
$gif = $gif->deconstructImages();
return new EncodedImage($gif->getImagesBlob(), 'image/gif');
return new EncodedImage($imagick->getImagesBlob(), 'image/gif');
}
}

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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());
}
}

View File

@ -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 $imagick)
{
//
}
public function getImagick(): Imagick
{
return $this->imagick;
}
public function getFrame(int $key = 0): ?FrameInterface
{
try {
$this->imagick->setIteratorIndex($key);
} catch (ImagickException $e) {
return null;
}
return new Frame($this->imagick->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->imagick->addImage($imagick);
return $this;
}
public function setLoops(int $count): ImageInterface
{
$this->imagick->setImageIterations($count);
return $this;
}
public function getLoops(): int
{
return $this->imagick->getImageIterations();
}
public function isAnimated(): bool
{
return $this->count() > 1;
}
public function count(): int
{
return $this->imagick->getNumberImages();
}
public function current()
{
$this->imagick->setIteratorIndex($this->iteratorIndex);
return new Frame($this->imagick->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->imagick->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

View File

@ -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

View File

@ -2,10 +2,13 @@
namespace Intervention\Image\Interfaces;
interface CollectionInterface
use Traversable;
interface CollectionInterface extends Traversable
{
public function push($item): CollectionInterface;
public function get(int $key);
public function get(int $key, $default = null);
public function has(int $key);
public function first();
public function last();
public function count(): int;

View File

@ -2,13 +2,12 @@
namespace Intervention\Image\Interfaces;
use Intervention\Image\Collection;
use Countable;
use Intervention\Image\EncodedImage;
use Traversable;
interface ImageInterface
interface ImageInterface extends Traversable, Countable
{
public function getIterator(): Collection;
public function getFrames(): Collection;
public function getFrame(int $key = 0): ?FrameInterface;
public function addFrame(FrameInterface $frame): ImageInterface;
public function setLoops(int $count): ImageInterface;
@ -21,7 +20,7 @@ interface ImageInterface
public function toWebp(int $quality = 75): EncodedImage;
public function toGif(): EncodedImage;
public function toPng(): EncodedImage;
public function pickColors(int $x, int $y): Collection;
public function pickColors(int $x, int $y): CollectionInterface;
public function pickColor(int $x, int $y, int $frame_key = 0): ?ColorInterface;
public function greyscale(): ImageInterface;
public function blur(int $amount = 5): ImageInterface;

View File

@ -86,6 +86,14 @@ class CollectionTest extends TestCase
$this->assertEquals('test', $collection->get(3, 'test'));
}
public function testHas(): void
{
$collection = new Collection(['foo', 'bar']);
$this->assertTrue($collection->has(0));
$this->assertTrue($collection->has(1));
$this->assertFalse($collection->has(2));
}
public function testToArray()
{
$collection = new Collection(['foo', 'bar', 'baz']);

View File

@ -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();

View File

@ -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

View File

@ -0,0 +1,40 @@
<?php
namespace Intervention\Image\Tests\Drivers\Imagick\Decoders;
use Intervention\Image\Drivers\Imagick\Decoders\BinaryImageDecoder;
use Intervention\Image\Drivers\Imagick\Image;
use Intervention\Image\Tests\TestCase;
class BinaryImageDecoderTest extends TestCase
{
public function testDecodePng(): void
{
$decoder = new BinaryImageDecoder();
$image = $decoder->decode(file_get_contents(__DIR__ . '/../../../images/tile.png'));
$this->assertInstanceOf(Image::class, $image);
$this->assertEquals(16, $image->getWidth());
$this->assertEquals(16, $image->getHeight());
$this->assertCount(1, $image);
}
public function testDecodeGif(): void
{
$decoder = new BinaryImageDecoder();
$image = $decoder->decode(file_get_contents(__DIR__ . '/../../../images/red.gif'));
$this->assertInstanceOf(Image::class, $image);
$this->assertEquals(16, $image->getWidth());
$this->assertEquals(16, $image->getHeight());
$this->assertCount(1, $image);
}
public function testDecodeAnimatedGif(): void
{
$decoder = new BinaryImageDecoder();
$image = $decoder->decode(file_get_contents(__DIR__ . '/../../../images/cats.gif'));
$this->assertInstanceOf(Image::class, $image);
$this->assertEquals(75, $image->getWidth());
$this->assertEquals(50, $image->getHeight());
$this->assertCount(4, $image);
}
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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());