1
0
mirror of https://github.com/Intervention/image.git synced 2025-08-24 14:32:52 +02:00

Implement config options

This commit is contained in:
Oliver Vogel
2024-05-09 09:58:10 +02:00
parent 55c64ef812
commit fa2bf7d793
31 changed files with 289 additions and 221 deletions

View File

@@ -9,9 +9,9 @@ use Intervention\Image\Interfaces\ConfigInterface;
class Config implements ConfigInterface
{
public function __construct(
protected bool $autoOrientate = true,
protected bool $autoOrientation = true,
protected bool $decodeAnimation = true,
protected mixed $blendingColor = 'ffffffff',
protected mixed $blendingColor = 'ffffff00',
) {
}
@@ -20,13 +20,34 @@ class Config implements ConfigInterface
return $this->decodeAnimation;
}
public function autoOrientate(): bool
public function setDecodeAnimation(bool $status): self
{
return $this->autoOrientate;
$this->decodeAnimation = $status;
return $this;
}
public function autoOrientation(): bool
{
return $this->autoOrientation;
}
public function setAutoOrientation(bool $status): self
{
$this->autoOrientation = $status;
return $this;
}
public function blendingColor(): mixed
{
return $this->blendingColor;
}
public function setBlendingColor(mixed $color): self
{
$this->blendingColor = $color;
return $this;
}
}

View File

@@ -65,8 +65,10 @@ abstract class AbstractDriver implements DriverInterface
return $object;
}
// return directly if object is already specialized
if ($object instanceof SpecializedInterface) {
// return directly and only attach driver if object is already specialized
if (($object instanceof SpecializedInterface)) {
$object->setDriver($this);
return $object;
}
@@ -81,7 +83,7 @@ abstract class AbstractDriver implements DriverInterface
);
}
// create driver specialized object with specializable properties of generic object
// create a driver specialized object with the specializable properties of generic object
$specialized = (new $specialized_classname(...$object->specializable()));
// attach driver

View File

@@ -8,14 +8,11 @@ use Intervention\Image\Exceptions\RuntimeException;
use Intervention\Image\Interfaces\ColorInterface;
use Intervention\Image\Interfaces\DecoderInterface;
use Intervention\Image\Interfaces\ImageInterface;
use Intervention\Image\Drivers\Gd\Decoders\Traits\CanDecodeGif;
use Intervention\Image\Exceptions\DecoderException;
use Intervention\Image\Modifiers\AlignRotationModifier;
class BinaryImageDecoder extends NativeObjectDecoder implements DecoderInterface
{
use CanDecodeGif;
/**
* {@inheritdoc}
*
@@ -63,7 +60,9 @@ class BinaryImageDecoder extends NativeObjectDecoder implements DecoderInterface
}
// adjust image orientation
$image->modify(new AlignRotationModifier());
if ($this->driver()->config()->autoOrientation()) {
$image->modify(new AlignRotationModifier());
}
return $image;
}

View File

@@ -4,7 +4,6 @@ declare(strict_types=1);
namespace Intervention\Image\Drivers\Gd\Decoders;
use Intervention\Image\Drivers\Gd\Decoders\Traits\CanDecodeGif;
use Intervention\Image\Exceptions\DecoderException;
use Intervention\Image\Interfaces\ColorInterface;
use Intervention\Image\Interfaces\DecoderInterface;
@@ -13,8 +12,6 @@ use Intervention\Image\Modifiers\AlignRotationModifier;
class FilePathImageDecoder extends NativeObjectDecoder implements DecoderInterface
{
use CanDecodeGif;
public function decode(mixed $input): ImageInterface|ColorInterface
{
if (!$this->isFile($input)) {
@@ -53,7 +50,9 @@ class FilePathImageDecoder extends NativeObjectDecoder implements DecoderInterfa
$image->setExif($this->extractExifData($input));
// adjust image orientation
$image->modify(new AlignRotationModifier());
if ($this->driver()->config()->autoOrientation()) {
$image->modify(new AlignRotationModifier());
}
return $image;
}

View File

@@ -5,13 +5,15 @@ declare(strict_types=1);
namespace Intervention\Image\Drivers\Gd\Decoders;
use GdImage;
use Intervention\Gif\Decoder as GifDecoder;
use Intervention\Gif\Splitter as GifSplitter;
use Intervention\Image\Drivers\Gd\Core;
use Intervention\Image\Drivers\Gd\Driver;
use Intervention\Image\Drivers\Gd\Frame;
use Intervention\Image\Exceptions\DecoderException;
use Intervention\Image\Exceptions\RuntimeException;
use Intervention\Image\Image;
use Intervention\Image\Interfaces\ImageInterface;
use Intervention\Image\Interfaces\ColorInterface;
use Intervention\Image\Interfaces\ImageInterface;
class NativeObjectDecoder extends AbstractDecoder
{
@@ -38,10 +40,67 @@ class NativeObjectDecoder extends AbstractDecoder
// build image instance
return new Image(
new Driver(),
$this->driver(),
new Core([
new Frame($input)
])
);
}
/**
* Decode image from given GIF source which can be either a file path or binary data
*
* Depending on the configuration, this is taken over by the native GD function
* or, if animations are required, by our own extended decoder.
*
* @param mixed $input
* @throws RuntimeException
* @return ImageInterface
*/
protected function decodeGif(mixed $input): ImageInterface
{
// create non-animated image depending on config
if (!$this->driver()->config()->decodeAnimation()) {
$native = match (true) {
$this->isGifFormat($input) => @imagecreatefromstring($input),
default => @imagecreatefromgif($input),
};
if ($native === false) {
throw new DecoderException('Unable to decode input.');
}
$image = self::decode($native);
$image->origin()->setMediaType('image/gif');
return $image;
}
// create empty core
$core = new Core();
$gif = GifDecoder::decode($input);
$splitter = GifSplitter::create($gif)->split();
$delays = $splitter->getDelays();
// set loops on core
if ($loops = $gif->getMainApplicationExtension()?->getLoops()) {
$core->setLoops($loops);
}
// add GDImage instances to core
foreach ($splitter->coalesceToResources() as $key => $native) {
$core->push(
new Frame($native, $delays[$key] / 100)
);
}
// create (possibly) animated image
$image = new Image($this->driver(), $core);
// set media type
$image->origin()->setMediaType('image/gif');
return $image;
}
}

View File

@@ -1,54 +0,0 @@
<?php
declare(strict_types=1);
namespace Intervention\Image\Drivers\Gd\Decoders\Traits;
use Intervention\Gif\Decoder as GifDecoder;
use Intervention\Gif\Splitter as GifSplitter;
use Intervention\Image\Drivers\Gd\Core;
use Intervention\Image\Drivers\Gd\Driver;
use Intervention\Image\Drivers\Gd\Frame;
use Intervention\Image\Exceptions\RuntimeException;
use Intervention\Image\Image;
use Intervention\Image\Interfaces\ImageInterface;
trait CanDecodeGif
{
/**
* Decode image from given GIF source which can be either a file path or binary data
*
* @param mixed $input
* @throws RuntimeException
* @return ImageInterface
*/
protected function decodeGif(mixed $input): ImageInterface
{
$gif = GifDecoder::decode($input);
$splitter = GifSplitter::create($gif)->split();
$delays = $splitter->getDelays();
// build core
$core = new Core();
// set loops on core
if ($loops = $gif->getMainApplicationExtension()?->getLoops()) {
$core->setLoops($loops);
}
// add GDImage instances to core
foreach ($splitter->coalesceToResources() as $key => $native) {
$core->push(
(new Frame($native))->setDelay($delays[$key] / 100)
);
}
// create image
$image = new Image(new Driver(), $core);
// set media type
$image->origin()->setMediaType('image/gif');
return $image;
}
}

View File

@@ -6,13 +6,13 @@ namespace Intervention\Image\Drivers\Imagick\Decoders;
use Imagick;
use Intervention\Image\Drivers\Imagick\Core;
use Intervention\Image\Drivers\Imagick\Driver;
use Intervention\Image\Drivers\SpecializableDecoder;
use Intervention\Image\Exceptions\DecoderException;
use Intervention\Image\Image;
use Intervention\Image\Interfaces\ColorInterface;
use Intervention\Image\Interfaces\ImageInterface;
use Intervention\Image\Modifiers\AlignRotationModifier;
use Intervention\Image\Modifiers\RemoveAnimationModifier;
class NativeObjectDecoder extends SpecializableDecoder
{
@@ -33,13 +33,21 @@ class NativeObjectDecoder extends SpecializableDecoder
$input = $input->coalesceImages();
}
// create image object
$image = new Image(
new Driver(),
$this->driver(),
new Core($input)
);
// discard animation depending on config
if (!$this->driver()->config()->decodeAnimation()) {
$image->modify(new RemoveAnimationModifier());
}
// adjust image rotatation
$image->modify(new AlignRotationModifier());
if ($this->driver()->config()->autoOrientation()) {
$image->modify(new AlignRotationModifier());
}
// set media type on origin
$image->origin()->setMediaType($input->getImageMimeType());

View File

@@ -13,7 +13,6 @@ use Intervention\Image\Analyzers\PixelColorsAnalyzer;
use Intervention\Image\Analyzers\ProfileAnalyzer;
use Intervention\Image\Analyzers\ResolutionAnalyzer;
use Intervention\Image\Analyzers\WidthAnalyzer;
use Intervention\Image\Colors\Rgb\Color;
use Intervention\Image\Encoders\AutoEncoder;
use Intervention\Image\Encoders\AvifEncoder;
use Intervention\Image\Encoders\BmpEncoder;
@@ -50,6 +49,7 @@ use Intervention\Image\Interfaces\ModifierInterface;
use Intervention\Image\Interfaces\ProfileInterface;
use Intervention\Image\Interfaces\ResolutionInterface;
use Intervention\Image\Interfaces\SizeInterface;
use Intervention\Image\Modifiers\AlignRotationModifier;
use Intervention\Image\Modifiers\BlendTransparencyModifier;
use Intervention\Image\Modifiers\BlurModifier;
use Intervention\Image\Modifiers\BrightnessModifier;
@@ -101,14 +101,6 @@ final class Image implements ImageInterface
*/
protected Origin $origin;
/**
* Color is mixed with transparent areas when converting to a format which
* does not support transparency.
*
* @var ColorInterface
*/
protected ColorInterface $blendingColor;
/**
* Create new instance
*
@@ -124,9 +116,6 @@ final class Image implements ImageInterface
protected CollectionInterface $exif = new Collection()
) {
$this->origin = new Origin();
$this->blendingColor = $this->colorspace()->importColor(
new Color(255, 255, 255, 0)
);
}
/**
@@ -418,7 +407,9 @@ final class Image implements ImageInterface
*/
public function blendingColor(): ColorInterface
{
return $this->blendingColor;
return $this->driver()->handleInput(
$this->driver()->config()->blendingColor()
);
}
/**
@@ -428,7 +419,9 @@ final class Image implements ImageInterface
*/
public function setBlendingColor(mixed $color): ImageInterface
{
$this->blendingColor = $this->driver()->handleInput($color);
$this->driver()->config()->setBlendingColor(
$this->driver()->handleInput($color)
);
return $this;
}
@@ -603,6 +596,16 @@ final class Image implements ImageInterface
return $this->modify(new RotateModifier($angle, $background));
}
/**
* {@inheritdoc}
*
* @see ImageInterface::orient()
*/
public function orient(): ImageInterface
{
return $this->modify(new AlignRotationModifier());
}
/**
* {@inheritdoc}
*

View File

@@ -8,6 +8,7 @@ use Intervention\Image\Interfaces\DriverInterface;
use Intervention\Image\Interfaces\ImageInterface;
use Intervention\Image\Drivers\Gd\Driver as GdDriver;
use Intervention\Image\Drivers\Imagick\Driver as ImagickDriver;
use Intervention\Image\Exceptions\DriverException;
use Intervention\Image\Interfaces\DecoderInterface;
use Intervention\Image\Interfaces\ImageManagerInterface;
@@ -41,6 +42,7 @@ final class ImageManager implements ImageManagerInterface
*
* @link https://image.intervention.io/v3/basics/image-manager#static-gd-driver-constructor
* @param mixed $options
* @throws DriverException
* @return ImageManager
*/
public static function gd(mixed ...$options): self
@@ -53,6 +55,7 @@ final class ImageManager implements ImageManagerInterface
*
* @link https://image.intervention.io/v3/basics/image-manager#static-imagick-driver-constructor
* @param mixed $options
* @throws DriverException
* @return ImageManager
*/
public static function imagick(mixed ...$options): self

View File

@@ -18,8 +18,10 @@ use Intervention\Image\Decoders\DataUriImageDecoder;
use Intervention\Image\Decoders\FilePathImageDecoder;
use Intervention\Image\Decoders\FilePointerImageDecoder;
use Intervention\Image\Decoders\ImageObjectDecoder;
use Intervention\Image\Decoders\NativeObjectDecoder;
use Intervention\Image\Decoders\SplFileInfoImageDecoder;
use Intervention\Image\Exceptions\DecoderException;
use Intervention\Image\Exceptions\DriverException;
use Intervention\Image\Exceptions\NotSupportedException;
use Intervention\Image\Interfaces\ColorInterface;
use Intervention\Image\Interfaces\DecoderInterface;
@@ -35,7 +37,7 @@ class InputHandler implements InputHandlerInterface
* @var array<string|DecoderInterface>
*/
protected array $decoders = [
// NativeObjectDecoder::class,
NativeObjectDecoder::class,
ImageObjectDecoder::class,
ColorObjectDecoder::class,
RgbHexColorDecoder::class,
@@ -80,9 +82,9 @@ class InputHandler implements InputHandlerInterface
*/
public function handle($input): ImageInterface|ColorInterface
{
foreach ($this->decoders as $decoderClassname) {
foreach ($this->decoders as $decoder) {
// resolve river specialized decoder
$decoder = $this->resolve($decoderClassname);
$decoder = $this->resolve($decoder);
try {
return $decoder->decode($input);
@@ -98,11 +100,20 @@ class InputHandler implements InputHandlerInterface
* Resolve the given classname to an decoder object
*
* @param string|DecoderInterface $decoder
* @return DecoderInterface
* @throws DriverException
* @throws NotSupportedException
* @return DecoderInterface
*/
private function resolve(string|DecoderInterface $decoder): DecoderInterface
{
if (($decoder instanceof DecoderInterface) && empty($this->driver)) {
return $decoder;
}
if (($decoder instanceof DecoderInterface) && !empty($this->driver)) {
return $this->driver->specialize($decoder);
}
if (empty($this->driver)) {
return new $decoder();
}

View File

@@ -7,6 +7,10 @@ namespace Intervention\Image\Interfaces;
interface ConfigInterface
{
public function decodeAnimation(): bool;
public function autoOrientate(): bool;
public function autoOrientation(): bool;
public function blendingColor(): mixed;
public function setBlendingColor(mixed $color): mixed;
}

View File

@@ -32,6 +32,7 @@ interface DriverInterface
*
* @param ModifierInterface|AnalyzerInterface|EncoderInterface|DecoderInterface $object
* @throws NotSupportedException
* @throws DriverException
* @return ModifierInterface|AnalyzerInterface|EncoderInterface|DecoderInterface
*/
public function specialize(

View File

@@ -248,6 +248,7 @@ interface ImageInterface extends IteratorAggregate, Countable
* does not support transparency.
*
* @link https://image.intervention.io/v3/basics/colors#transparency
* @throws RuntimeException
* @return ColorInterface
*/
public function blendingColor(): ColorInterface;
@@ -430,6 +431,14 @@ interface ImageInterface extends IteratorAggregate, Countable
*/
public function rotate(float $angle, mixed $background = 'ffffff'): self;
/**
* Rotate the image to be upright according to exif information
*
* @throws RuntimeException
* @return ImageInterface
*/
public function orient(): self;
/**
* Draw text on image
*

View File

@@ -4,6 +4,8 @@ declare(strict_types=1);
namespace Intervention\Image\Interfaces;
use Intervention\Image\Exceptions\DriverException;
interface SpecializableInterface
{
/**
@@ -18,6 +20,7 @@ interface SpecializableInterface
* Set the driver for which the object is specialized
*
* @param DriverInterface $driver
* @throws DriverException
* @return SpecializableInterface
*/
public function setDriver(DriverInterface $driver): self;

View File

@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace Intervention\Image\Traits;
use Intervention\Image\Exceptions\DriverException;
use Intervention\Image\Interfaces\DriverInterface;
use Intervention\Image\Interfaces\SpecializableInterface;
use ReflectionClass;
@@ -53,8 +54,30 @@ trait CanBeDriverSpecialized
*/
public function setDriver(DriverInterface $driver): SpecializableInterface
{
if (!$this->belongsToDriver($driver)) {
throw new DriverException(
"Class '" . $this::class . "' can not be used with " . $driver->id() . " driver."
);
}
$this->driver = $driver;
return $this;
}
/**
* Determine if the given object belongs to the driver's namespace
*
* @param object $object
* @return bool
*/
protected function belongsToDriver(object $object): bool
{
$driverId = function (object $object): string|bool {
$id = substr($object::class, 27);
return strstr($id, "\\", true);
};
return $driverId($this) === $driverId($object);
}
}

View File

@@ -15,20 +15,20 @@ use PHPUnit\Framework\ExpectationFailedException;
abstract class BaseTestCase extends MockeryTestCase
{
public function getTestResourcePath($filename = 'test.jpg'): string
public static function getTestResourcePath($filename = 'test.jpg'): string
{
return sprintf('%s/resources/%s', __DIR__, $filename);
}
public function getTestResourceData($filename = 'test.jpg'): string
public static function getTestResourceData($filename = 'test.jpg'): string
{
return file_get_contents($this->getTestResourcePath($filename));
return file_get_contents(self::getTestResourcePath($filename));
}
public function getTestResourcePointer($filename = 'test.jpg')
{
$pointer = fopen('php://temp', 'rw');
fputs($pointer, $this->getTestResourceData($filename));
fputs($pointer, self::getTestResourceData($filename));
rewind($pointer);
return $pointer;

View File

@@ -4,8 +4,8 @@ declare(strict_types=1);
namespace Intervention\Image\Tests;
use Intervention\Image\Decoders\FilePathImageDecoder;
use Intervention\Image\Drivers\Gd\Core;
use Intervention\Image\Drivers\Gd\Decoders\FilePathImageDecoder;
use Intervention\Image\Drivers\Gd\Driver;
use Intervention\Image\Drivers\Gd\Frame;
use Intervention\Image\Image;
@@ -14,7 +14,7 @@ abstract class GdTestCase extends BaseTestCase
{
public function readTestImage($filename = 'test.jpg'): Image
{
return (new FilePathImageDecoder())->decode(
return (new Driver())->specialize(new FilePathImageDecoder())->decode(
$this->getTestResourcePath($filename)
);
}

View File

@@ -6,8 +6,8 @@ namespace Intervention\Image\Tests;
use Imagick;
use ImagickPixel;
use Intervention\Image\Decoders\FilePathImageDecoder;
use Intervention\Image\Drivers\Imagick\Core;
use Intervention\Image\Drivers\Imagick\Decoders\FilePathImageDecoder;
use Intervention\Image\Drivers\Imagick\Driver;
use Intervention\Image\Image;
@@ -15,7 +15,7 @@ abstract class ImagickTestCase extends BaseTestCase
{
public function readTestImage($filename = 'test.jpg'): Image
{
return (new FilePathImageDecoder())->decode(
return (new Driver())->specialize(new FilePathImageDecoder())->decode(
$this->getTestResourcePath($filename)
);
}

View File

@@ -7,6 +7,7 @@ namespace Intervention\Image\Tests\Unit\Drivers\Gd\Decoders;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\RequiresPhpExtension;
use Intervention\Image\Drivers\Gd\Decoders\Base64ImageDecoder;
use Intervention\Image\Drivers\Gd\Driver;
use Intervention\Image\Exceptions\DecoderException;
use Intervention\Image\Image;
use Intervention\Image\Tests\BaseTestCase;
@@ -20,6 +21,7 @@ final class Base64ImageDecoderTest extends BaseTestCase
protected function setUp(): void
{
$this->decoder = new Base64ImageDecoder();
$this->decoder->setDriver(new Driver());
}
public function testDecode(): void

View File

@@ -7,6 +7,7 @@ namespace Intervention\Image\Tests\Unit\Drivers\Gd\Decoders;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\RequiresPhpExtension;
use Intervention\Image\Drivers\Gd\Decoders\BinaryImageDecoder;
use Intervention\Image\Drivers\Gd\Driver;
use Intervention\Image\Image;
use Intervention\Image\Tests\BaseTestCase;
@@ -14,10 +15,17 @@ use Intervention\Image\Tests\BaseTestCase;
#[CoversClass(\Intervention\Image\Drivers\Gd\Decoders\BinaryImageDecoder::class)]
final class BinaryImageDecoderTest extends BaseTestCase
{
protected BinaryImageDecoder $decoder;
protected function setUp(): void
{
$this->decoder = new BinaryImageDecoder();
$this->decoder->setDriver(new Driver());
}
public function testDecodePng(): void
{
$decoder = new BinaryImageDecoder();
$image = $decoder->decode(file_get_contents($this->getTestResourcePath('tile.png')));
$image = $this->decoder->decode(file_get_contents($this->getTestResourcePath('tile.png')));
$this->assertInstanceOf(Image::class, $image);
$this->assertEquals(16, $image->width());
$this->assertEquals(16, $image->height());
@@ -26,8 +34,7 @@ final class BinaryImageDecoderTest extends BaseTestCase
public function testDecodeGif(): void
{
$decoder = new BinaryImageDecoder();
$image = $decoder->decode(file_get_contents($this->getTestResourcePath('red.gif')));
$image = $this->decoder->decode(file_get_contents($this->getTestResourcePath('red.gif')));
$this->assertInstanceOf(Image::class, $image);
$this->assertEquals(16, $image->width());
$this->assertEquals(16, $image->height());
@@ -36,8 +43,7 @@ final class BinaryImageDecoderTest extends BaseTestCase
public function testDecodeAnimatedGif(): void
{
$decoder = new BinaryImageDecoder();
$image = $decoder->decode(file_get_contents($this->getTestResourcePath('cats.gif')));
$image = $this->decoder->decode(file_get_contents($this->getTestResourcePath('cats.gif')));
$this->assertInstanceOf(Image::class, $image);
$this->assertEquals(75, $image->width());
$this->assertEquals(50, $image->height());
@@ -46,8 +52,7 @@ final class BinaryImageDecoderTest extends BaseTestCase
public function testDecodeJpegWithExif(): void
{
$decoder = new BinaryImageDecoder();
$image = $decoder->decode(file_get_contents($this->getTestResourcePath('exif.jpg')));
$image = $this->decoder->decode(file_get_contents($this->getTestResourcePath('exif.jpg')));
$this->assertInstanceOf(Image::class, $image);
$this->assertEquals(16, $image->width());
$this->assertEquals(16, $image->height());

View File

@@ -7,6 +7,7 @@ namespace Intervention\Image\Tests\Unit\Drivers\Gd\Decoders;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\RequiresPhpExtension;
use Intervention\Image\Drivers\Gd\Decoders\DataUriImageDecoder;
use Intervention\Image\Drivers\Gd\Driver;
use Intervention\Image\Exceptions\DecoderException;
use Intervention\Image\Image;
use Intervention\Image\Tests\BaseTestCase;
@@ -21,6 +22,7 @@ final class DataUriImageDecoderTest extends BaseTestCase
protected function setUp(): void
{
$this->decoder = new DataUriImageDecoder();
$this->decoder->setDriver(new Driver());
}
public function testDecode(): void

View File

@@ -7,10 +7,11 @@ namespace Intervention\Image\Tests\Unit\Drivers\Gd\Decoders;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\RequiresPhpExtension;
use Intervention\Image\Drivers\Gd\Decoders\FilePathImageDecoder;
use Intervention\Image\Drivers\Gd\Driver;
use Intervention\Image\Exceptions\DecoderException;
use Intervention\Image\Image;
use Intervention\Image\Tests\BaseTestCase;
use stdClass;
use PHPUnit\Framework\Attributes\DataProvider;
#[RequiresPhpExtension('gd')]
#[CoversClass(\Intervention\Image\Drivers\Gd\Decoders\FilePathImageDecoder::class)]
@@ -21,32 +22,35 @@ final class FilePathImageDecoderTest extends BaseTestCase
protected function setUp(): void
{
$this->decoder = new FilePathImageDecoder();
$this->decoder->setDriver(new Driver());
}
public function testDecode(): void
#[DataProvider('validFormatPathsProvider')]
public function testDecode(string $path, bool $result): void
{
$result = $this->decoder->decode(
$this->getTestResourcePath()
);
if ($result === false) {
$this->expectException(DecoderException::class);
}
$this->assertInstanceOf(Image::class, $result);
$result = $this->decoder->decode($path);
if ($result === true) {
$this->assertInstanceOf(Image::class, $result);
}
}
public function testDecoderNonString(): void
public static function validFormatPathsProvider(): array
{
$this->expectException(DecoderException::class);
$this->decoder->decode(new stdClass());
}
public function testDecoderNoPath(): void
{
$this->expectException(DecoderException::class);
$this->decoder->decode('no-path');
}
public function testDecoderTooLongPath(): void
{
$this->expectException(DecoderException::class);
$this->decoder->decode(str_repeat('x', PHP_MAXPATHLEN + 1));
return [
[self::getTestResourcePath('cats.gif'), true],
[self::getTestResourcePath('animation.gif'), true],
[self::getTestResourcePath('red.gif'), true],
[self::getTestResourcePath('green.gif'), true],
[self::getTestResourcePath('blue.gif'), true],
[self::getTestResourcePath('gradient.bmp'), true],
[self::getTestResourcePath('circle.png'), true],
['no-path', false],
[str_repeat('x', PHP_MAXPATHLEN + 1), false],
];
}
}

View File

@@ -7,6 +7,7 @@ namespace Intervention\Image\Tests\Unit\Drivers\Gd\Decoders;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\RequiresPhpExtension;
use Intervention\Image\Drivers\Gd\Decoders\FilePointerImageDecoder;
use Intervention\Image\Drivers\Gd\Driver;
use Intervention\Image\Image;
use Intervention\Image\Tests\GdTestCase;
@@ -17,6 +18,8 @@ final class FilePointerImageDecoderTest extends GdTestCase
public function testDecode(): void
{
$decoder = new FilePointerImageDecoder();
$decoder->setDriver(new Driver());
$fp = fopen($this->getTestResourcePath('test.jpg'), 'r');
$result = $decoder->decode($fp);
$this->assertInstanceOf(Image::class, $result);

View File

@@ -7,6 +7,7 @@ namespace Intervention\Image\Tests\Unit\Drivers\Gd\Decoders;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\RequiresPhpExtension;
use Intervention\Image\Drivers\Gd\Decoders\SplFileInfoImageDecoder;
use Intervention\Image\Drivers\Gd\Driver;
use Intervention\Image\Image;
use Intervention\Image\Tests\BaseTestCase;
use SplFileInfo;
@@ -18,6 +19,8 @@ final class SplFileInfoImageDecoderTest extends BaseTestCase
public function testDecode(): void
{
$decoder = new SplFileInfoImageDecoder();
$decoder->setDriver(new Driver());
$result = $decoder->decode(
new SplFileInfo($this->getTestResourcePath('blue.gif'))
);

View File

@@ -1,57 +0,0 @@
<?php
declare(strict_types=1);
namespace Intervention\Image\Tests\Unit\Drivers\Gd\Traits;
use Intervention\Image\Drivers\Gd\Decoders\Traits\CanDecodeGif;
use Intervention\Image\Interfaces\ImageInterface;
use Intervention\Image\Tests\BaseTestCase;
use Mockery;
final class CanDecodeGifTest extends BaseTestCase
{
public function testDecodeGifFromBinaryAnimation(): void
{
$decoder = Mockery::mock(new class () {
use CanDecodeGif;
})->makePartial();
$result = $decoder->decodeGif($this->getTestResourceData('animation.gif'));
$this->assertInstanceOf(ImageInterface::class, $result);
$this->assertEquals('image/gif', $result->origin()->mediaType());
}
public function testDecodeGifFromBinaryStatic(): void
{
$decoder = Mockery::mock(new class () {
use CanDecodeGif;
})->makePartial();
$result = $decoder->decodeGif($this->getTestResourceData('red.gif'));
$this->assertInstanceOf(ImageInterface::class, $result);
$this->assertEquals('image/gif', $result->origin()->mediaType());
}
public function testDecodeGifFromPathAnimation(): void
{
$decoder = Mockery::mock(new class () {
use CanDecodeGif;
})->makePartial();
$result = $decoder->decodeGif($this->getTestResourcePath('animation.gif'));
$this->assertInstanceOf(ImageInterface::class, $result);
$this->assertEquals('image/gif', $result->origin()->mediaType());
}
public function testDecodeGifFromPathStatic(): void
{
$decoder = Mockery::mock(new class () {
use CanDecodeGif;
})->makePartial();
$result = $decoder->decodeGif($this->getTestResourcePath('red.gif'));
$this->assertInstanceOf(ImageInterface::class, $result);
$this->assertEquals('image/gif', $result->origin()->mediaType());
}
}

View File

@@ -7,6 +7,7 @@ namespace Intervention\Image\Tests\Unit\Drivers\Imagick\Decoders;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\RequiresPhpExtension;
use Intervention\Image\Drivers\Imagick\Decoders\Base64ImageDecoder;
use Intervention\Image\Drivers\Imagick\Driver;
use Intervention\Image\Exceptions\DecoderException;
use Intervention\Image\Image;
use Intervention\Image\Tests\BaseTestCase;
@@ -20,6 +21,7 @@ final class Base64ImageDecoderTest extends BaseTestCase
protected function setUp(): void
{
$this->decoder = new Base64ImageDecoder();
$this->decoder->setDriver(new Driver());
}
public function testDecode(): void

View File

@@ -7,6 +7,7 @@ namespace Intervention\Image\Tests\Unit\Drivers\Imagick\Decoders;
use Intervention\Image\Colors\Cmyk\Colorspace as CmykColorspace;
use Intervention\Image\Colors\Rgb\Colorspace as RgbColorspace;
use Intervention\Image\Drivers\Imagick\Decoders\BinaryImageDecoder;
use Intervention\Image\Drivers\Imagick\Driver;
use Intervention\Image\Exceptions\DecoderException;
use Intervention\Image\Image;
use Intervention\Image\Tests\BaseTestCase;
@@ -14,10 +15,17 @@ use stdClass;
final class BinaryImageDecoderTest extends BaseTestCase
{
protected BinaryImageDecoder $decoder;
protected function setUp(): void
{
$this->decoder = new BinaryImageDecoder();
$this->decoder->setDriver(new Driver());
}
public function testDecodePng(): void
{
$decoder = new BinaryImageDecoder();
$image = $decoder->decode(file_get_contents($this->getTestResourcePath('tile.png')));
$image = $this->decoder->decode(file_get_contents($this->getTestResourcePath('tile.png')));
$this->assertInstanceOf(Image::class, $image);
$this->assertInstanceOf(RgbColorspace::class, $image->colorspace());
$this->assertEquals(16, $image->width());
@@ -27,8 +35,7 @@ final class BinaryImageDecoderTest extends BaseTestCase
public function testDecodeGif(): void
{
$decoder = new BinaryImageDecoder();
$image = $decoder->decode(file_get_contents($this->getTestResourcePath('red.gif')));
$image = $this->decoder->decode(file_get_contents($this->getTestResourcePath('red.gif')));
$this->assertInstanceOf(Image::class, $image);
$this->assertEquals(16, $image->width());
$this->assertEquals(16, $image->height());
@@ -37,8 +44,7 @@ final class BinaryImageDecoderTest extends BaseTestCase
public function testDecodeAnimatedGif(): void
{
$decoder = new BinaryImageDecoder();
$image = $decoder->decode(file_get_contents($this->getTestResourcePath('cats.gif')));
$image = $this->decoder->decode(file_get_contents($this->getTestResourcePath('cats.gif')));
$this->assertInstanceOf(Image::class, $image);
$this->assertEquals(75, $image->width());
$this->assertEquals(50, $image->height());
@@ -47,8 +53,7 @@ final class BinaryImageDecoderTest extends BaseTestCase
public function testDecodeJpegWithExif(): void
{
$decoder = new BinaryImageDecoder();
$image = $decoder->decode(file_get_contents($this->getTestResourcePath('exif.jpg')));
$image = $this->decoder->decode(file_get_contents($this->getTestResourcePath('exif.jpg')));
$this->assertInstanceOf(Image::class, $image);
$this->assertEquals(16, $image->width());
$this->assertEquals(16, $image->height());
@@ -58,16 +63,14 @@ final class BinaryImageDecoderTest extends BaseTestCase
public function testDecodeCmykImage(): void
{
$decoder = new BinaryImageDecoder();
$image = $decoder->decode(file_get_contents($this->getTestResourcePath('cmyk.jpg')));
$image = $this->decoder->decode(file_get_contents($this->getTestResourcePath('cmyk.jpg')));
$this->assertInstanceOf(Image::class, $image);
$this->assertInstanceOf(CmykColorspace::class, $image->colorspace());
}
public function testDecodeNonString(): void
{
$decoder = new BinaryImageDecoder();
$this->expectException(DecoderException::class);
$decoder->decode(new stdClass());
$this->decoder->decode(new stdClass());
}
}

View File

@@ -7,6 +7,7 @@ namespace Intervention\Image\Tests\Unit\Drivers\Imagick\Decoders;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\RequiresPhpExtension;
use Intervention\Image\Drivers\Imagick\Decoders\DataUriImageDecoder;
use Intervention\Image\Drivers\Imagick\Driver;
use Intervention\Image\Exceptions\DecoderException;
use Intervention\Image\Image;
use Intervention\Image\Tests\BaseTestCase;
@@ -21,6 +22,7 @@ final class DataUriImageDecoderTest extends BaseTestCase
protected function setUp(): void
{
$this->decoder = new DataUriImageDecoder();
$this->decoder->setDriver(new Driver());
}
public function testDecode(): void

View File

@@ -7,10 +7,11 @@ namespace Intervention\Image\Tests\Unit\Drivers\Imagick\Decoders;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\RequiresPhpExtension;
use Intervention\Image\Drivers\Imagick\Decoders\FilePathImageDecoder;
use Intervention\Image\Drivers\Imagick\Driver;
use Intervention\Image\Exceptions\DecoderException;
use Intervention\Image\Image;
use Intervention\Image\Tests\BaseTestCase;
use stdClass;
use PHPUnit\Framework\Attributes\DataProvider;
#[RequiresPhpExtension('imagick')]
#[CoversClass(\Intervention\Image\Drivers\Imagick\Decoders\FilePathImageDecoder::class)]
@@ -21,32 +22,35 @@ final class FilePathImageDecoderTest extends BaseTestCase
protected function setUp(): void
{
$this->decoder = new FilePathImageDecoder();
$this->decoder->setDriver(new Driver());
}
public function testDecode(): void
#[DataProvider('validFormatPathsProvider')]
public function testDecode(string $path, bool $result): void
{
$result = $this->decoder->decode(
$this->getTestResourcePath()
);
if ($result === false) {
$this->expectException(DecoderException::class);
}
$this->assertInstanceOf(Image::class, $result);
$result = $this->decoder->decode($path);
if ($result === true) {
$this->assertInstanceOf(Image::class, $result);
}
}
public function testDecoderNonString(): void
public static function validFormatPathsProvider(): array
{
$this->expectException(DecoderException::class);
$this->decoder->decode(new stdClass());
}
public function testDecoderNoPath(): void
{
$this->expectException(DecoderException::class);
$this->decoder->decode('no-path');
}
public function testDecoderTooLongPath(): void
{
$this->expectException(DecoderException::class);
$this->decoder->decode(str_repeat('x', PHP_MAXPATHLEN + 1));
return [
[self::getTestResourcePath('cats.gif'), true],
[self::getTestResourcePath('animation.gif'), true],
[self::getTestResourcePath('red.gif'), true],
[self::getTestResourcePath('green.gif'), true],
[self::getTestResourcePath('blue.gif'), true],
[self::getTestResourcePath('gradient.bmp'), true],
[self::getTestResourcePath('circle.png'), true],
['no-path', false],
[str_repeat('x', PHP_MAXPATHLEN + 1), false],
];
}
}

View File

@@ -7,6 +7,7 @@ namespace Intervention\Image\Tests\Unit\Drivers\Imagick\Decoders;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\RequiresPhpExtension;
use Intervention\Image\Drivers\Imagick\Decoders\FilePointerImageDecoder;
use Intervention\Image\Drivers\Imagick\Driver;
use Intervention\Image\Image;
use Intervention\Image\Tests\ImagickTestCase;
@@ -17,6 +18,7 @@ final class FilePointerImageDecoderTest extends ImagickTestCase
public function testDecode(): void
{
$decoder = new FilePointerImageDecoder();
$decoder->setDriver(new Driver());
$fp = fopen($this->getTestResourcePath('test.jpg'), 'r');
$result = $decoder->decode($fp);
$this->assertInstanceOf(Image::class, $result);

View File

@@ -7,6 +7,7 @@ namespace Intervention\Image\Tests\Unit\Drivers\Imagick\Decoders;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\RequiresPhpExtension;
use Intervention\Image\Drivers\Imagick\Decoders\SplFileInfoImageDecoder;
use Intervention\Image\Drivers\Imagick\Driver;
use Intervention\Image\Image;
use Intervention\Image\Tests\BaseTestCase;
use SplFileInfo;
@@ -18,6 +19,7 @@ final class SplFileInfoImageDecoderTest extends BaseTestCase
public function testDecode(): void
{
$decoder = new SplFileInfoImageDecoder();
$decoder->setDriver(new Driver());
$result = $decoder->decode(
new SplFileInfo($this->getTestResourcePath('blue.gif'))
);