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

Add animation creation

This commit is contained in:
Oliver Vogel
2023-11-26 16:40:02 +01:00
parent 6d333c8fd6
commit d59614578f
9 changed files with 177 additions and 0 deletions

View File

@@ -45,4 +45,14 @@ class Core extends Collection implements CoreInterface
return $this;
}
public function first(): FrameInterface
{
return parent::first();
}
public function last(): FrameInterface
{
return parent::last();
}
}

View File

@@ -7,15 +7,26 @@ use Intervention\Image\Image;
use Intervention\Image\Interfaces\ColorInterface;
use Intervention\Image\Interfaces\ColorProcessorInterface;
use Intervention\Image\Interfaces\ColorspaceInterface;
use Intervention\Image\Interfaces\DriverInterface;
use Intervention\Image\Interfaces\ImageInterface;
class Driver extends AbstractDriver
{
/**
* {@inheritdoc}
*
* @see DriverInterface::id()
*/
public function id(): string
{
return 'GD';
}
/**
* {@inheritdoc}
*
* @see DriverInterface::createImage()
*/
public function createImage(int $width, int $height): ImageInterface
{
// build new transparent GDImage
@@ -34,11 +45,59 @@ class Driver extends AbstractDriver
);
}
/**
* {@inheritdoc}
*
* @see DriverInterface::createAnimation()
*/
public function createAnimation(callable $init): ImageInterface
{
$animation = new class ($this)
{
public function __construct(
protected DriverInterface $driver,
public Core $core = new Core()
) {
}
public function add($source, float $delay = 1): self
{
$this->core->add(
$this->driver->handleInput($source)->core()->first()->setDelay($delay)
);
return $this;
}
public function __invoke(): ImageInterface
{
return new Image(
$this->driver,
$this->core
);
}
};
$init($animation);
return call_user_func($animation);
}
/**
* {@inheritdoc}
*
* @see DriverInterface::handleInput()
*/
public function handleInput(mixed $input): ImageInterface|ColorInterface
{
return (new InputHandler())->handle($input);
}
/**
* {@inheritdoc}
*
* @see DriverInterface::colorProcessor()
*/
public function colorProcessor(ColorspaceInterface $colorspace): ColorProcessorInterface
{
return new ColorProcessor($colorspace);

View File

@@ -110,4 +110,14 @@ class Core implements CoreInterface, Iterator
return $this;
}
public function first(): FrameInterface
{
return $this->frame(0);
}
public function last(): FrameInterface
{
return $this->frame($this->count());
}
}

View File

@@ -9,15 +9,26 @@ use Intervention\Image\Image;
use Intervention\Image\Interfaces\ColorInterface;
use Intervention\Image\Interfaces\ColorProcessorInterface;
use Intervention\Image\Interfaces\ColorspaceInterface;
use Intervention\Image\Interfaces\DriverInterface;
use Intervention\Image\Interfaces\ImageInterface;
class Driver extends AbstractDriver
{
/**
* {@inheritdoc}
*
* @see DriverInterface::id()
*/
public function id(): string
{
return 'Imagick';
}
/**
* {@inheritdoc}
*
* @see DriverInterface::createImage()
*/
public function createImage(int $width, int $height): ImageInterface
{
$background = new ImagickPixel('rgba(0, 0, 0, 0)');
@@ -32,11 +43,63 @@ class Driver extends AbstractDriver
return new Image($this, new Core($imagick));
}
/**
* {@inheritdoc}
*
* @see DriverInterface::createAnimation()
*/
public function createAnimation(callable $init): ImageInterface
{
$imagick = new Imagick();
$imagick->setFormat('gif');
$animation = new class ($this, $imagick)
{
public function __construct(
protected DriverInterface $driver,
public Imagick $imagick
) {
}
public function add($source, float $delay = 1): self
{
$native = $this->driver->handleInput($source)->core()->native();
$native->setImageDelay($delay * 100);
$this->imagick->addImage($native);
return $this;
}
public function __invoke(): ImageInterface
{
return new Image(
$this->driver,
new Core($this->imagick)
);
}
};
$init($animation);
return call_user_func($animation);
}
/**
* {@inheritdoc}
*
* @see DriverInterface::handleInput()
*/
public function handleInput(mixed $input): ImageInterface|ColorInterface
{
return (new InputHandler())->handle($input);
}
/**
* {@inheritdoc}
*
* @see DriverInterface::colorProcessor()
*/
public function colorProcessor(ColorspaceInterface $colorspace): ColorProcessorInterface
{
return new ColorProcessor($colorspace);

View File

@@ -142,6 +142,18 @@ final class Image implements ImageInterface, Countable
return $this->core->loops();
}
/**
* {@inheritdoc}
*
* @see ImageInterface::setLoops()
*/
public function setLoops(int $loops): ImageInterface
{
$this->core->setLoops($loops);
return $this;
}
/**
* {@inheritdoc}
*

View File

@@ -41,6 +41,11 @@ final class ImageManager
return $this->driver->handleInput($input);
}
public function animate(callable $init): ImageInterface
{
return $this->driver->createAnimation($init);
}
private static function resolveDriver(string|DriverInterface $driver): DriverInterface
{
if (is_object($driver)) {

View File

@@ -59,4 +59,6 @@ interface CoreInterface extends Traversable
* @return CoreInterface
*/
public function setLoops(int $loops): CoreInterface;
public function first(): FrameInterface;
}

View File

@@ -28,6 +28,14 @@ interface DriverInterface
*/
public function createImage(int $width, int $height): ImageInterface;
/**
* Create new animated image
*
* @param callable $init
* @return ImageInterface
*/
public function createAnimation(callable $init): ImageInterface;
/**
* Handle given input by decoding it to ImageInterface or ColorInterface
*

View File

@@ -94,6 +94,14 @@ interface ImageInterface extends IteratorAggregate, Countable
*/
public function loops(): int;
/**
* Set loop count of animated image
*
* @param int $loops
* @return ImageInterface
*/
public function setLoops(int $loops): ImageInterface;
/**
* Return exif data of current image
*