mirror of
https://github.com/Intervention/image.git
synced 2025-08-12 08:54:03 +02:00
Refactor architecture
This commit is contained in:
@@ -13,7 +13,6 @@ class Collection implements CollectionInterface, IteratorAggregate, Countable
|
|||||||
{
|
{
|
||||||
public function __construct(protected array $items = [])
|
public function __construct(protected array $items = [])
|
||||||
{
|
{
|
||||||
//
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -27,6 +26,11 @@ class Collection implements CollectionInterface, IteratorAggregate, Countable
|
|||||||
return new self($items);
|
return new self($items);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function has(int|string $key): bool
|
||||||
|
{
|
||||||
|
return array_key_exists($key, $this->items);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns Iterator
|
* Returns Iterator
|
||||||
*
|
*
|
||||||
|
@@ -3,7 +3,7 @@
|
|||||||
namespace Intervention\Image\Colors\Cmyk\Decoders;
|
namespace Intervention\Image\Colors\Cmyk\Decoders;
|
||||||
|
|
||||||
use Intervention\Image\Colors\Cmyk\Color;
|
use Intervention\Image\Colors\Cmyk\Color;
|
||||||
use Intervention\Image\Drivers\Abstract\Decoders\AbstractDecoder;
|
use Intervention\Image\Drivers\AbstractDecoder;
|
||||||
use Intervention\Image\Exceptions\DecoderException;
|
use Intervention\Image\Exceptions\DecoderException;
|
||||||
use Intervention\Image\Interfaces\ColorInterface;
|
use Intervention\Image\Interfaces\ColorInterface;
|
||||||
use Intervention\Image\Interfaces\DecoderInterface;
|
use Intervention\Image\Interfaces\DecoderInterface;
|
||||||
|
@@ -7,5 +7,4 @@ use Intervention\Image\Interfaces\ProfileInterface;
|
|||||||
|
|
||||||
class Profile extends GenericData implements ProfileInterface
|
class Profile extends GenericData implements ProfileInterface
|
||||||
{
|
{
|
||||||
//
|
|
||||||
}
|
}
|
||||||
|
@@ -3,7 +3,7 @@
|
|||||||
namespace Intervention\Image\Colors\Rgb\Decoders;
|
namespace Intervention\Image\Colors\Rgb\Decoders;
|
||||||
|
|
||||||
use Intervention\Image\Colors\Rgb\Color;
|
use Intervention\Image\Colors\Rgb\Color;
|
||||||
use Intervention\Image\Drivers\Abstract\Decoders\AbstractDecoder;
|
use Intervention\Image\Drivers\AbstractDecoder;
|
||||||
use Intervention\Image\Exceptions\DecoderException;
|
use Intervention\Image\Exceptions\DecoderException;
|
||||||
use Intervention\Image\Interfaces\ColorInterface;
|
use Intervention\Image\Interfaces\ColorInterface;
|
||||||
use Intervention\Image\Interfaces\DecoderInterface;
|
use Intervention\Image\Interfaces\DecoderInterface;
|
||||||
|
@@ -3,7 +3,7 @@
|
|||||||
namespace Intervention\Image\Colors\Rgb\Decoders;
|
namespace Intervention\Image\Colors\Rgb\Decoders;
|
||||||
|
|
||||||
use Intervention\Image\Colors\Rgb\Color;
|
use Intervention\Image\Colors\Rgb\Color;
|
||||||
use Intervention\Image\Drivers\Abstract\Decoders\AbstractDecoder;
|
use Intervention\Image\Drivers\AbstractDecoder;
|
||||||
use Intervention\Image\Exceptions\DecoderException;
|
use Intervention\Image\Exceptions\DecoderException;
|
||||||
use Intervention\Image\Interfaces\ColorInterface;
|
use Intervention\Image\Interfaces\ColorInterface;
|
||||||
use Intervention\Image\Interfaces\DecoderInterface;
|
use Intervention\Image\Interfaces\DecoderInterface;
|
||||||
|
@@ -19,7 +19,7 @@ use Intervention\Image\Traits\CanHandleInput;
|
|||||||
use Intervention\Image\Traits\CanResolveDriverClass;
|
use Intervention\Image\Traits\CanResolveDriverClass;
|
||||||
use Intervention\Image\Traits\CanRunCallback;
|
use Intervention\Image\Traits\CanRunCallback;
|
||||||
|
|
||||||
abstract class AbstractImage implements ImageInterface
|
abstract class DELETE___AbstractImage implements ImageInterface
|
||||||
{
|
{
|
||||||
use CanResolveDriverClass;
|
use CanResolveDriverClass;
|
||||||
use CanHandleInput;
|
use CanHandleInput;
|
||||||
|
@@ -8,7 +8,7 @@ use Intervention\Image\Interfaces\ColorInterface;
|
|||||||
use Intervention\Image\Interfaces\ImageInterface;
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
use Intervention\Image\Interfaces\InputHandlerInterface;
|
use Intervention\Image\Interfaces\InputHandlerInterface;
|
||||||
|
|
||||||
abstract class AbstractInputHandler implements InputHandlerInterface
|
abstract class DELETE____AbstractInputHandler implements InputHandlerInterface
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Array of decoders which will be stacked into to the input handler chain
|
* Array of decoders which will be stacked into to the input handler chain
|
||||||
|
@@ -9,7 +9,7 @@ use Intervention\Image\Interfaces\DecoderInterface;
|
|||||||
use Intervention\Image\Interfaces\ImageInterface;
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
use Intervention\Image\Traits\CanBuildFilePointer;
|
use Intervention\Image\Traits\CanBuildFilePointer;
|
||||||
|
|
||||||
abstract class AbstractDecoder implements DecoderInterface
|
abstract class DELETE___AbstractDecoder implements DecoderInterface
|
||||||
{
|
{
|
||||||
use CanBuildFilePointer;
|
use CanBuildFilePointer;
|
||||||
|
|
||||||
|
@@ -14,18 +14,11 @@ use Intervention\Image\Interfaces\PointInterface;
|
|||||||
use Intervention\Image\Traits\CanCheckType;
|
use Intervention\Image\Traits\CanCheckType;
|
||||||
use Intervention\Image\Traits\CanHandleInput;
|
use Intervention\Image\Traits\CanHandleInput;
|
||||||
|
|
||||||
class AbstractDrawModifier
|
class DELETE__AbstractDrawModifier
|
||||||
{
|
{
|
||||||
use CanHandleInput;
|
use CanHandleInput;
|
||||||
use CanCheckType;
|
use CanCheckType;
|
||||||
|
|
||||||
public function __construct(
|
|
||||||
protected PointInterface $position,
|
|
||||||
protected DrawableInterface $drawable
|
|
||||||
) {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
public function drawable(): DrawableInterface
|
public function drawable(): DrawableInterface
|
||||||
{
|
{
|
||||||
return $this->drawable;
|
return $this->drawable;
|
||||||
|
@@ -6,14 +6,13 @@ use Intervention\Image\Geometry\Rectangle;
|
|||||||
use Intervention\Image\Interfaces\ImageInterface;
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
use Intervention\Image\Interfaces\SizeInterface;
|
use Intervention\Image\Interfaces\SizeInterface;
|
||||||
|
|
||||||
abstract class AbstractFitModifier
|
abstract class DELETE___AbstractFitModifier
|
||||||
{
|
{
|
||||||
public function __construct(
|
public function __construct(
|
||||||
protected int $width,
|
protected int $width,
|
||||||
protected int $height,
|
protected int $height,
|
||||||
protected string $position = 'center'
|
protected string $position = 'center'
|
||||||
) {
|
) {
|
||||||
//
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getCropSize(ImageInterface $image): SizeInterface
|
protected function getCropSize(ImageInterface $image): SizeInterface
|
||||||
|
@@ -7,7 +7,7 @@ use Intervention\Image\Interfaces\ImageInterface;
|
|||||||
use Intervention\Image\Interfaces\SizeInterface;
|
use Intervention\Image\Interfaces\SizeInterface;
|
||||||
use Intervention\Image\Traits\CanCheckType;
|
use Intervention\Image\Traits\CanCheckType;
|
||||||
|
|
||||||
abstract class AbstractPadModifier
|
abstract class DELETE___AbstractPadModifier
|
||||||
{
|
{
|
||||||
use CanCheckType;
|
use CanCheckType;
|
||||||
|
|
||||||
@@ -20,14 +20,14 @@ abstract class AbstractPadModifier
|
|||||||
//
|
//
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getCropSize(ImageInterface $image): SizeInterface
|
public function getCropSize(ImageInterface $image): SizeInterface
|
||||||
{
|
{
|
||||||
return $image->size()
|
return $image->size()
|
||||||
->contain($this->width, $this->height)
|
->contain($this->width, $this->height)
|
||||||
->alignPivotTo($this->getResizeSize($image), $this->position);
|
->alignPivotTo($this->getResizeSize($image), $this->position);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getResizeSize(ImageInterface $image): SizeInterface
|
public function getResizeSize(ImageInterface $image): SizeInterface
|
||||||
{
|
{
|
||||||
return new Rectangle($this->width, $this->height);
|
return new Rectangle($this->width, $this->height);
|
||||||
}
|
}
|
||||||
|
@@ -6,7 +6,7 @@ use Intervention\Image\Exceptions\InputException;
|
|||||||
use Intervention\Image\Interfaces\FrameInterface;
|
use Intervention\Image\Interfaces\FrameInterface;
|
||||||
use Intervention\Image\Interfaces\ModifierInterface;
|
use Intervention\Image\Interfaces\ModifierInterface;
|
||||||
|
|
||||||
abstract class AbstractRemoveAnimationModifier implements ModifierInterface
|
abstract class DELETE___AbstractRemoveAnimationModifier implements ModifierInterface
|
||||||
{
|
{
|
||||||
protected function chosenFrame($image, int|string $position): FrameInterface
|
protected function chosenFrame($image, int|string $position): FrameInterface
|
||||||
{
|
{
|
||||||
|
@@ -8,7 +8,7 @@ use Intervention\Image\Interfaces\ColorInterface;
|
|||||||
use Intervention\Image\Traits\CanCheckType;
|
use Intervention\Image\Traits\CanCheckType;
|
||||||
use Intervention\Image\Traits\CanHandleInput;
|
use Intervention\Image\Traits\CanHandleInput;
|
||||||
|
|
||||||
abstract class AbstractRotateModifier
|
abstract class DELETE____AbstractRotateModifier
|
||||||
{
|
{
|
||||||
use CanHandleInput;
|
use CanHandleInput;
|
||||||
use CanCheckType;
|
use CanCheckType;
|
||||||
|
155
src/Drivers/AbstractDecoder.php
Normal file
155
src/Drivers/AbstractDecoder.php
Normal file
@@ -0,0 +1,155 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Intervention\Image\Drivers;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
|
use Intervention\Image\Collection;
|
||||||
|
use Intervention\Image\Exceptions\DecoderException;
|
||||||
|
use Intervention\Image\Interfaces\CollectionInterface;
|
||||||
|
use Intervention\Image\Interfaces\ColorInterface;
|
||||||
|
use Intervention\Image\Interfaces\DecoderInterface;
|
||||||
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
|
use Intervention\Image\Traits\CanBuildFilePointer;
|
||||||
|
|
||||||
|
abstract class AbstractDecoder implements DecoderInterface
|
||||||
|
{
|
||||||
|
use CanBuildFilePointer;
|
||||||
|
|
||||||
|
public function __construct(protected ?AbstractDecoder $successor = null)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
final public function handle($input): ImageInterface|ColorInterface
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$decoded = $this->decode($input);
|
||||||
|
} catch (DecoderException $e) {
|
||||||
|
if (!$this->hasSuccessor()) {
|
||||||
|
throw new DecoderException($e->getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->successor->handle($input);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $decoded;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function hasSuccessor(): bool
|
||||||
|
{
|
||||||
|
return $this->successor !== null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return media type (MIME) of given input
|
||||||
|
*
|
||||||
|
* @param string $input
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function mediaType(string $input): string
|
||||||
|
{
|
||||||
|
$pointer = $this->buildFilePointer($input);
|
||||||
|
$type = mime_content_type($pointer);
|
||||||
|
fclose($pointer);
|
||||||
|
|
||||||
|
return $type;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function decodeExifData(string $image_data): CollectionInterface
|
||||||
|
{
|
||||||
|
if (!function_exists('exif_read_data')) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$pointer = $this->buildFilePointer($image_data);
|
||||||
|
$data = @exif_read_data($pointer, null, true);
|
||||||
|
fclose($pointer);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
$data = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Collection(is_array($data) ? $data : []);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function isValidBase64($input): bool
|
||||||
|
{
|
||||||
|
if (!is_string($input)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return base64_encode(base64_decode($input)) === str_replace(["\n", "\r"], '', $input);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse data uri
|
||||||
|
*
|
||||||
|
* @param mixed $value
|
||||||
|
* @return object
|
||||||
|
*/
|
||||||
|
protected function parseDataUri($value): object
|
||||||
|
{
|
||||||
|
$pattern = "/^data:(?P<mediatype>\w+\/[-+.\w]+)?" .
|
||||||
|
"(?P<parameters>(;[-\w]+=[-\w]+)*)(?P<base64>;base64)?,(?P<data>.*)/";
|
||||||
|
|
||||||
|
$result = preg_match($pattern, $value, $matches);
|
||||||
|
|
||||||
|
return new class ($matches, $result)
|
||||||
|
{
|
||||||
|
private $matches;
|
||||||
|
private $result;
|
||||||
|
|
||||||
|
public function __construct($matches, $result)
|
||||||
|
{
|
||||||
|
$this->matches = $matches;
|
||||||
|
$this->result = $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isValid(): bool
|
||||||
|
{
|
||||||
|
return (bool) $this->result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function mediaType(): ?string
|
||||||
|
{
|
||||||
|
if (isset($this->matches['mediatype']) && !empty($this->matches['mediatype'])) {
|
||||||
|
return $this->matches['mediatype'];
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function hasMediaType(): bool
|
||||||
|
{
|
||||||
|
return !empty($this->mediaType());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function parameters(): array
|
||||||
|
{
|
||||||
|
if (isset($this->matches['parameters']) && !empty($this->matches['parameters'])) {
|
||||||
|
return explode(';', trim($this->matches['parameters'], ';'));
|
||||||
|
}
|
||||||
|
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isBase64Encoded(): bool
|
||||||
|
{
|
||||||
|
if (isset($this->matches['base64']) && $this->matches['base64'] === ';base64') {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function data(): ?string
|
||||||
|
{
|
||||||
|
if (isset($this->matches['data']) && !empty($this->matches['data'])) {
|
||||||
|
return $this->matches['data'];
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
33
src/Drivers/AbstractDriver.php
Normal file
33
src/Drivers/AbstractDriver.php
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Intervention\Image\Drivers;
|
||||||
|
|
||||||
|
use Intervention\Image\Interfaces\DriverInterface;
|
||||||
|
use ReflectionClass;
|
||||||
|
|
||||||
|
abstract class AbstractDriver implements DriverInterface
|
||||||
|
{
|
||||||
|
public function resolve(object $input): object
|
||||||
|
{
|
||||||
|
$ns = (new ReflectionClass($this))->getNamespaceName();
|
||||||
|
$classname = (new ReflectionClass($input))->getShortName();
|
||||||
|
|
||||||
|
preg_match("/(?P<dept>[A-Z][a-z]+)$/", $classname, $matches);
|
||||||
|
$department = array_key_exists('dept', $matches) ? $matches['dept'] : null;
|
||||||
|
$department = match ($department) {
|
||||||
|
'Modifier', 'Writer' => 'Modifiers',
|
||||||
|
'Encoder' => 'Encoders',
|
||||||
|
default => null,
|
||||||
|
};
|
||||||
|
|
||||||
|
$specialized = implode("\\", array_filter([
|
||||||
|
$ns,
|
||||||
|
$department,
|
||||||
|
$classname
|
||||||
|
], function ($dept) {
|
||||||
|
return !empty($dept);
|
||||||
|
}));
|
||||||
|
|
||||||
|
return new $specialized($input, $this);
|
||||||
|
}
|
||||||
|
}
|
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Intervention\Image\Drivers\Abstract;
|
namespace Intervention\Image\Drivers;
|
||||||
|
|
||||||
use Intervention\Image\Interfaces\ColorInterface;
|
use Intervention\Image\Interfaces\ColorInterface;
|
||||||
use Intervention\Image\Interfaces\FontInterface;
|
use Intervention\Image\Interfaces\FontInterface;
|
52
src/Drivers/AbstractInputHandler.php
Normal file
52
src/Drivers/AbstractInputHandler.php
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Intervention\Image\Drivers;
|
||||||
|
|
||||||
|
use Intervention\Image\Drivers\AbstractDecoder;
|
||||||
|
use Intervention\Image\Exceptions\DecoderException;
|
||||||
|
use Intervention\Image\Interfaces\ColorInterface;
|
||||||
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
|
use Intervention\Image\Interfaces\InputHandlerInterface;
|
||||||
|
|
||||||
|
abstract class AbstractInputHandler implements InputHandlerInterface
|
||||||
|
{
|
||||||
|
protected array $decoders = [];
|
||||||
|
|
||||||
|
public function __construct(array $decoders = [])
|
||||||
|
{
|
||||||
|
$this->decoders = count($decoders) ? $decoders : $this->decoders;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*
|
||||||
|
* @see InputHandlerInterface::handle()
|
||||||
|
*/
|
||||||
|
public function handle($input): ImageInterface|ColorInterface
|
||||||
|
{
|
||||||
|
return $this->chain()->handle($input);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stack the decoder array into a nested decoder object
|
||||||
|
*
|
||||||
|
* @return AbstractDecoder
|
||||||
|
*/
|
||||||
|
protected function chain(): AbstractDecoder
|
||||||
|
{
|
||||||
|
if (count($this->decoders) == 0) {
|
||||||
|
throw new DecoderException('No decoders found in ' . get_class($this));
|
||||||
|
}
|
||||||
|
|
||||||
|
// get instance of last decoder in stack
|
||||||
|
list($classname) = array_slice(array_reverse($this->decoders), 0, 1);
|
||||||
|
$chain = new $classname();
|
||||||
|
|
||||||
|
// build decoder chain
|
||||||
|
foreach (array_slice(array_reverse($this->decoders), 1) as $classname) {
|
||||||
|
$chain = new $classname($chain);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $chain;
|
||||||
|
}
|
||||||
|
}
|
37
src/Drivers/DrawModifier.php
Normal file
37
src/Drivers/DrawModifier.php
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Intervention\Image\Drivers;
|
||||||
|
|
||||||
|
use Intervention\Image\Exceptions\DecoderException;
|
||||||
|
use Intervention\Image\Geometry\Point;
|
||||||
|
use Intervention\Image\Interfaces\ColorInterface;
|
||||||
|
|
||||||
|
abstract class DrawModifier extends DriverModifier
|
||||||
|
{
|
||||||
|
public function position(): Point
|
||||||
|
{
|
||||||
|
return $this->drawable->pivot();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function backgroundColor(): ColorInterface
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$color = $this->driver()->handleInput($this->drawable->backgroundColor());
|
||||||
|
} catch (DecoderException $e) {
|
||||||
|
return $this->driver()->handleInput('transparent');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $color;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function borderColor(): ColorInterface
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$color = $this->driver()->handleInput($this->drawable->borderColor());
|
||||||
|
} catch (DecoderException $e) {
|
||||||
|
return $this->driver()->handleInput('transparent');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $color;
|
||||||
|
}
|
||||||
|
}
|
47
src/Drivers/DriverEncoder.php
Normal file
47
src/Drivers/DriverEncoder.php
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Intervention\Image\Drivers;
|
||||||
|
|
||||||
|
use Intervention\Image\Interfaces\DriverInterface;
|
||||||
|
use Intervention\Image\Interfaces\EncoderInterface;
|
||||||
|
|
||||||
|
abstract class DriverEncoder implements EncoderInterface
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
protected EncoderInterface $encoder,
|
||||||
|
protected DriverInterface $driver
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public function driver(): DriverInterface
|
||||||
|
{
|
||||||
|
return $this->driver;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Magic method to read attributes of underlying endcoder
|
||||||
|
*
|
||||||
|
* @param string $name
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function __get(string $name): mixed
|
||||||
|
{
|
||||||
|
return $this->encoder->$name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get return value of callback through output buffer
|
||||||
|
*
|
||||||
|
* @param callable $callback
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function getBuffered(callable $callback): string
|
||||||
|
{
|
||||||
|
ob_start();
|
||||||
|
$callback();
|
||||||
|
$buffer = ob_get_contents();
|
||||||
|
ob_end_clean();
|
||||||
|
|
||||||
|
return $buffer;
|
||||||
|
}
|
||||||
|
}
|
43
src/Drivers/DriverModifier.php
Normal file
43
src/Drivers/DriverModifier.php
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Intervention\Image\Drivers;
|
||||||
|
|
||||||
|
use Intervention\Image\Interfaces\DriverInterface;
|
||||||
|
use Intervention\Image\Interfaces\ModifierInterface;
|
||||||
|
|
||||||
|
abstract class DriverModifier implements ModifierInterface
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
protected ModifierInterface $modifier,
|
||||||
|
protected DriverInterface $driver
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public function driver(): DriverInterface
|
||||||
|
{
|
||||||
|
return $this->driver;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Magic method to read attributes of underlying modifier
|
||||||
|
*
|
||||||
|
* @param string $name
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function __get(string $name): mixed
|
||||||
|
{
|
||||||
|
return $this->modifier->$name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Magic method to call methods of underlying modifier
|
||||||
|
*
|
||||||
|
* @param string $name
|
||||||
|
* @param array $arguments
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function __call(string $name, array $arguments): mixed
|
||||||
|
{
|
||||||
|
return $this->modifier->$name(...$arguments);
|
||||||
|
}
|
||||||
|
}
|
54
src/Drivers/Gd/ColorProcessor.php
Normal file
54
src/Drivers/Gd/ColorProcessor.php
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Intervention\Image\Drivers\Gd;
|
||||||
|
|
||||||
|
use Intervention\Image\Colors\Rgb\Channels\Alpha;
|
||||||
|
use Intervention\Image\Colors\Rgb\Channels\Blue;
|
||||||
|
use Intervention\Image\Colors\Rgb\Channels\Green;
|
||||||
|
use Intervention\Image\Colors\Rgb\Channels\Red;
|
||||||
|
use Intervention\Image\Colors\Rgb\Colorspace;
|
||||||
|
use Intervention\Image\Interfaces\ColorInterface;
|
||||||
|
use Intervention\Image\Interfaces\ColorProcessorInterface;
|
||||||
|
use Intervention\Image\Interfaces\ColorspaceInterface;
|
||||||
|
|
||||||
|
class ColorProcessor implements ColorProcessorInterface
|
||||||
|
{
|
||||||
|
public function __construct(protected ColorspaceInterface $colorspace = new Colorspace())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function colorToNative(ColorInterface $color): int
|
||||||
|
{
|
||||||
|
$r = $color->channel(Red::class)->value();
|
||||||
|
$g = $color->channel(Green::class)->value();
|
||||||
|
$b = $color->channel(Blue::class)->value();
|
||||||
|
$a = $color->channel(Alpha::class)->value();
|
||||||
|
|
||||||
|
// convert alpha value to gd alpha
|
||||||
|
// ([opaque]255-0[transparent]) to ([opaque]0-127[transparent])
|
||||||
|
$a = (int) $this->convertRange($a, 0, 255, 127, 0);
|
||||||
|
|
||||||
|
return ($a << 24) + ($r << 16) + ($g << 8) + $b;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert input in range (min) to (max) to the corresponding value
|
||||||
|
* in target range (targetMin) to (targetMax).
|
||||||
|
*
|
||||||
|
* @param float|int $input
|
||||||
|
* @param float|int $min
|
||||||
|
* @param float|int $max
|
||||||
|
* @param float|int $targetMin
|
||||||
|
* @param float|int $targetMax
|
||||||
|
* @return float|int
|
||||||
|
*/
|
||||||
|
protected function convertRange(
|
||||||
|
float|int $input,
|
||||||
|
float|int $min,
|
||||||
|
float|int $max,
|
||||||
|
float|int $targetMin,
|
||||||
|
float|int $targetMax
|
||||||
|
): float|int {
|
||||||
|
return ceil(((($input - $min) * ($targetMax - $targetMin)) / ($max - $min)) + $targetMin);
|
||||||
|
}
|
||||||
|
}
|
51
src/Drivers/Gd/Core.php
Normal file
51
src/Drivers/Gd/Core.php
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Intervention\Image\Drivers\Gd;
|
||||||
|
|
||||||
|
use Intervention\Image\Collection;
|
||||||
|
use Intervention\Image\Colors\Rgb\Colorspace as RgbColorspace;
|
||||||
|
use Intervention\Image\Interfaces\ColorspaceInterface;
|
||||||
|
use Intervention\Image\Interfaces\CoreInterface;
|
||||||
|
use Intervention\Image\Interfaces\FrameInterface;
|
||||||
|
|
||||||
|
class Core extends Collection implements CoreInterface
|
||||||
|
{
|
||||||
|
protected int $loops = 0;
|
||||||
|
|
||||||
|
public function native()
|
||||||
|
{
|
||||||
|
return $this->first()->data();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function width(): int
|
||||||
|
{
|
||||||
|
return imagesx($this->native());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function height(): int
|
||||||
|
{
|
||||||
|
return imagesy($this->native());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function frame(int $position): FrameInterface
|
||||||
|
{
|
||||||
|
return $this->getAtPosition($position);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function loops(): int
|
||||||
|
{
|
||||||
|
return $this->loops;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setLoops(int $loops): self
|
||||||
|
{
|
||||||
|
$this->loops = $loops;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function colorspace(): ColorspaceInterface
|
||||||
|
{
|
||||||
|
return new RgbColorspace();
|
||||||
|
}
|
||||||
|
}
|
@@ -2,17 +2,17 @@
|
|||||||
|
|
||||||
namespace Intervention\Image\Drivers\Gd\Decoders;
|
namespace Intervention\Image\Drivers\Gd\Decoders;
|
||||||
|
|
||||||
use GdImage;
|
use Intervention\Image\Drivers\AbstractDecoder;
|
||||||
use Intervention\Image\Collection;
|
|
||||||
use Intervention\Image\Drivers\Abstract\Decoders\AbstractDecoder;
|
|
||||||
use Intervention\Image\Drivers\Gd\Frame;
|
use Intervention\Image\Drivers\Gd\Frame;
|
||||||
use Intervention\Image\Drivers\Gd\Image;
|
|
||||||
use Intervention\Image\Interfaces\ColorInterface;
|
use Intervention\Image\Interfaces\ColorInterface;
|
||||||
use Intervention\Image\Interfaces\DecoderInterface;
|
use Intervention\Image\Interfaces\DecoderInterface;
|
||||||
use Intervention\Image\Interfaces\ImageInterface;
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
use Intervention\Gif\Decoder as GifDecoder;
|
use Intervention\Gif\Decoder as GifDecoder;
|
||||||
use Intervention\Gif\Splitter as GifSplitter;
|
use Intervention\Gif\Splitter as GifSplitter;
|
||||||
|
use Intervention\Image\Drivers\Gd\Core;
|
||||||
|
use Intervention\Image\Drivers\Gd\Driver;
|
||||||
use Intervention\Image\Exceptions\DecoderException;
|
use Intervention\Image\Exceptions\DecoderException;
|
||||||
|
use Intervention\Image\Image;
|
||||||
|
|
||||||
class BinaryImageDecoder extends AbstractDecoder implements DecoderInterface
|
class BinaryImageDecoder extends AbstractDecoder implements DecoderInterface
|
||||||
{
|
{
|
||||||
@@ -26,40 +26,45 @@ class BinaryImageDecoder extends AbstractDecoder implements DecoderInterface
|
|||||||
return $this->decodeGif($input); // decode (animated) gif
|
return $this->decodeGif($input); // decode (animated) gif
|
||||||
}
|
}
|
||||||
|
|
||||||
$gd = $this->coreFromString($input);
|
|
||||||
|
|
||||||
// build image instance
|
// build image instance
|
||||||
$image = new Image(new Collection([new Frame($gd)]));
|
$image = new Image(
|
||||||
$image->setExif($this->decodeExifData($input));
|
new Driver(),
|
||||||
|
$this->coreFromString($input),
|
||||||
|
$this->decodeExifData($input)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $image;
|
||||||
|
|
||||||
// fix image orientation
|
// fix image orientation
|
||||||
return match ($image->exif('IFD0.Orientation')) {
|
// return match ($image->exif('IFD0.Orientation')) {
|
||||||
2 => $image->flip(),
|
// 2 => $image->flip(),
|
||||||
3 => $image->rotate(180),
|
// 3 => $image->rotate(180),
|
||||||
4 => $image->rotate(180)->flip(),
|
// 4 => $image->rotate(180)->flip(),
|
||||||
5 => $image->rotate(270)->flip(),
|
// 5 => $image->rotate(270)->flip(),
|
||||||
6 => $image->rotate(270),
|
// 6 => $image->rotate(270),
|
||||||
7 => $image->rotate(90)->flip(),
|
// 7 => $image->rotate(90)->flip(),
|
||||||
8 => $image->rotate(90),
|
// 8 => $image->rotate(90),
|
||||||
default => $image
|
// default => $image
|
||||||
};
|
// };
|
||||||
}
|
}
|
||||||
|
|
||||||
private function coreFromString(string $input): GdImage
|
private function coreFromString(string $input): Core
|
||||||
{
|
{
|
||||||
$gd = @imagecreatefromstring($input);
|
$data = @imagecreatefromstring($input);
|
||||||
|
|
||||||
if ($gd === false) {
|
if ($data === false) {
|
||||||
throw new DecoderException('Unable to decode input');
|
throw new DecoderException('Unable to decode input');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!imageistruecolor($gd)) {
|
if (!imageistruecolor($data)) {
|
||||||
imagepalettetotruecolor($gd);
|
imagepalettetotruecolor($data);
|
||||||
}
|
}
|
||||||
|
|
||||||
imagesavealpha($gd, true);
|
imagesavealpha($data, true);
|
||||||
|
|
||||||
return $gd;
|
return new Core([
|
||||||
|
new Frame($data)
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function decodeGif(string $input): ImageInterface
|
private function decodeGif(string $input): ImageInterface
|
||||||
@@ -68,22 +73,26 @@ class BinaryImageDecoder extends AbstractDecoder implements DecoderInterface
|
|||||||
|
|
||||||
if (!$gif->isAnimated()) {
|
if (!$gif->isAnimated()) {
|
||||||
return new Image(
|
return new Image(
|
||||||
new Collection([new Frame(
|
new Driver(),
|
||||||
$this->coreFromString($input)
|
$this->coreFromString($input)
|
||||||
)]),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$image = new Image(new Collection());
|
|
||||||
$image->setLoops($gif->getMainApplicationExtension()?->getLoops());
|
|
||||||
|
|
||||||
$splitter = GifSplitter::create($gif)->split();
|
$splitter = GifSplitter::create($gif)->split();
|
||||||
|
|
||||||
$delays = $splitter->getDelays();
|
$delays = $splitter->getDelays();
|
||||||
foreach ($splitter->coalesceToResources() as $key => $gd) {
|
|
||||||
$image->addFrame((new Frame($gd))->setDelay($delays[$key] / 100));
|
// build core
|
||||||
|
$core = new Core();
|
||||||
|
$core->setLoops($gif->getMainApplicationExtension()?->getLoops());
|
||||||
|
foreach ($splitter->coalesceToResources() as $key => $data) {
|
||||||
|
$core->push(
|
||||||
|
(new Frame($data))->setDelay($delays[$key] / 100)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $image;
|
return new Image(
|
||||||
|
new Driver(),
|
||||||
|
$core
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
namespace Intervention\Image\Drivers\Gd\Decoders;
|
namespace Intervention\Image\Drivers\Gd\Decoders;
|
||||||
|
|
||||||
use Intervention\Image\Drivers\Abstract\Decoders\AbstractDecoder;
|
use Intervention\Image\Drivers\AbstractDecoder;
|
||||||
use Intervention\Image\Exceptions\DecoderException;
|
use Intervention\Image\Exceptions\DecoderException;
|
||||||
use Intervention\Image\Interfaces\ColorInterface;
|
use Intervention\Image\Interfaces\ColorInterface;
|
||||||
use Intervention\Image\Interfaces\DecoderInterface;
|
use Intervention\Image\Interfaces\DecoderInterface;
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
namespace Intervention\Image\Drivers\Gd\Decoders;
|
namespace Intervention\Image\Drivers\Gd\Decoders;
|
||||||
|
|
||||||
use Intervention\Image\Drivers\Abstract\Decoders\AbstractDecoder;
|
use Intervention\Image\Drivers\AbstractDecoder;
|
||||||
use Intervention\Image\Exceptions\DecoderException;
|
use Intervention\Image\Exceptions\DecoderException;
|
||||||
use Intervention\Image\Interfaces\ColorInterface;
|
use Intervention\Image\Interfaces\ColorInterface;
|
||||||
use Intervention\Image\Interfaces\DecoderInterface;
|
use Intervention\Image\Interfaces\DecoderInterface;
|
||||||
|
40
src/Drivers/Gd/Driver.php
Normal file
40
src/Drivers/Gd/Driver.php
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Intervention\Image\Drivers\Gd;
|
||||||
|
|
||||||
|
use Intervention\Image\Drivers\AbstractDriver;
|
||||||
|
use Intervention\Image\Image;
|
||||||
|
use Intervention\Image\Interfaces\ColorInterface;
|
||||||
|
use Intervention\Image\Interfaces\ColorspaceInterface;
|
||||||
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
|
|
||||||
|
class Driver extends AbstractDriver
|
||||||
|
{
|
||||||
|
public function createImage(int $width, int $height): ImageInterface
|
||||||
|
{
|
||||||
|
// build new transparent GDImage
|
||||||
|
$data = imagecreatetruecolor($width, $height);
|
||||||
|
imagesavealpha($data, true);
|
||||||
|
$background = imagecolorallocatealpha($data, 255, 0, 255, 127);
|
||||||
|
imagealphablending($data, false);
|
||||||
|
imagefill($data, 0, 0, $background);
|
||||||
|
imagecolortransparent($data, $background);
|
||||||
|
|
||||||
|
return new Image(
|
||||||
|
$this,
|
||||||
|
new Core([
|
||||||
|
new Frame($data)
|
||||||
|
])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handleInput(mixed $input): ImageInterface|ColorInterface
|
||||||
|
{
|
||||||
|
return (new InputHandler())->handle($input);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function colorToNative(ColorInterface $color, ColorspaceInterface $colorspace): mixed
|
||||||
|
{
|
||||||
|
return (new ColorProcessor($colorspace))->colorToNative($color);
|
||||||
|
}
|
||||||
|
}
|
9
src/Drivers/Gd/Element.php
Normal file
9
src/Drivers/Gd/Element.php
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Intervention\Image\Drivers\Gd;
|
||||||
|
|
||||||
|
use Intervention\Image\Collection;
|
||||||
|
|
||||||
|
class Element extends Collection
|
||||||
|
{
|
||||||
|
}
|
@@ -2,22 +2,17 @@
|
|||||||
|
|
||||||
namespace Intervention\Image\Drivers\Gd\Encoders;
|
namespace Intervention\Image\Drivers\Gd\Encoders;
|
||||||
|
|
||||||
use Intervention\Image\Drivers\Abstract\Encoders\AbstractEncoder;
|
use Intervention\Image\Drivers\DriverEncoder;
|
||||||
use Intervention\Image\EncodedImage;
|
use Intervention\Image\EncodedImage;
|
||||||
use Intervention\Image\Interfaces\EncoderInterface;
|
|
||||||
use Intervention\Image\Interfaces\ImageInterface;
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
|
|
||||||
class AvifEncoder extends AbstractEncoder implements EncoderInterface
|
class AvifEncoder extends DriverEncoder
|
||||||
{
|
{
|
||||||
public function __construct(int $quality)
|
|
||||||
{
|
|
||||||
$this->quality = $quality;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function encode(ImageInterface $image): EncodedImage
|
public function encode(ImageInterface $image): EncodedImage
|
||||||
{
|
{
|
||||||
$data = $this->getBuffered(function () use ($image) {
|
$gd = $image->core()->native();
|
||||||
imageavif($image->frame()->core(), null, $this->quality);
|
$data = $this->getBuffered(function () use ($gd) {
|
||||||
|
imageavif($gd, null, $this->quality);
|
||||||
});
|
});
|
||||||
|
|
||||||
return new EncodedImage($data, 'image/avif');
|
return new EncodedImage($data, 'image/avif');
|
||||||
|
@@ -2,24 +2,19 @@
|
|||||||
|
|
||||||
namespace Intervention\Image\Drivers\Gd\Encoders;
|
namespace Intervention\Image\Drivers\Gd\Encoders;
|
||||||
|
|
||||||
use Intervention\Image\Drivers\Abstract\Encoders\AbstractEncoder;
|
use Intervention\Image\Drivers\DriverEncoder;
|
||||||
use Intervention\Image\Drivers\Gd\Modifiers\LimitColorsModifier;
|
use Intervention\Image\Modifiers\LimitColorsModifier;
|
||||||
use Intervention\Image\EncodedImage;
|
use Intervention\Image\EncodedImage;
|
||||||
use Intervention\Image\Interfaces\EncoderInterface;
|
|
||||||
use Intervention\Image\Interfaces\ImageInterface;
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
|
|
||||||
class BmpEncoder extends AbstractEncoder implements EncoderInterface
|
class BmpEncoder extends DriverEncoder
|
||||||
{
|
{
|
||||||
public function __construct(protected int $color_limit = 0)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
public function encode(ImageInterface $image): EncodedImage
|
public function encode(ImageInterface $image): EncodedImage
|
||||||
{
|
{
|
||||||
$image = $image->modify(new LimitColorsModifier($this->color_limit));
|
$image = $image->modify(new LimitColorsModifier($this->color_limit));
|
||||||
$data = $this->getBuffered(function () use ($image) {
|
$gd = $image->core()->native();
|
||||||
imagebmp($image->frame()->core(), null, false);
|
$data = $this->getBuffered(function () use ($gd) {
|
||||||
|
imagebmp($gd, null, false);
|
||||||
});
|
});
|
||||||
|
|
||||||
return new EncodedImage($data, 'image/bmp');
|
return new EncodedImage($data, 'image/bmp');
|
||||||
|
@@ -3,19 +3,13 @@
|
|||||||
namespace Intervention\Image\Drivers\Gd\Encoders;
|
namespace Intervention\Image\Drivers\Gd\Encoders;
|
||||||
|
|
||||||
use Intervention\Gif\Builder as GifBuilder;
|
use Intervention\Gif\Builder as GifBuilder;
|
||||||
use Intervention\Image\Drivers\Abstract\Encoders\AbstractEncoder;
|
use Intervention\Image\Drivers\DriverEncoder;
|
||||||
use Intervention\Image\Drivers\Gd\Modifiers\LimitColorsModifier;
|
use Intervention\Image\Modifiers\LimitColorsModifier;
|
||||||
use Intervention\Image\EncodedImage;
|
use Intervention\Image\EncodedImage;
|
||||||
use Intervention\Image\Interfaces\EncoderInterface;
|
|
||||||
use Intervention\Image\Interfaces\ImageInterface;
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
|
|
||||||
class GifEncoder extends AbstractEncoder implements EncoderInterface
|
class GifEncoder extends DriverEncoder
|
||||||
{
|
{
|
||||||
public function __construct(protected int $color_limit = 0)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
public function encode(ImageInterface $image): EncodedImage
|
public function encode(ImageInterface $image): EncodedImage
|
||||||
{
|
{
|
||||||
if ($image->isAnimated()) {
|
if ($image->isAnimated()) {
|
||||||
@@ -23,8 +17,9 @@ class GifEncoder extends AbstractEncoder implements EncoderInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
$image = $image->modify(new LimitColorsModifier($this->color_limit));
|
$image = $image->modify(new LimitColorsModifier($this->color_limit));
|
||||||
$data = $this->getBuffered(function () use ($image) {
|
$gd = $image->core()->native();
|
||||||
imagegif($image->frame()->core());
|
$data = $this->getBuffered(function () use ($gd) {
|
||||||
|
imagegif($gd);
|
||||||
});
|
});
|
||||||
|
|
||||||
return new EncodedImage($data, 'image/gif');
|
return new EncodedImage($data, 'image/gif');
|
||||||
@@ -40,7 +35,7 @@ class GifEncoder extends AbstractEncoder implements EncoderInterface
|
|||||||
|
|
||||||
foreach ($image as $frame) {
|
foreach ($image as $frame) {
|
||||||
$builder->addFrame(
|
$builder->addFrame(
|
||||||
$this->encode($frame->toImage()),
|
$this->encode($frame->toImage($image->driver())),
|
||||||
$frame->delay()
|
$frame->delay()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@@ -2,22 +2,17 @@
|
|||||||
|
|
||||||
namespace Intervention\Image\Drivers\Gd\Encoders;
|
namespace Intervention\Image\Drivers\Gd\Encoders;
|
||||||
|
|
||||||
use Intervention\Image\Drivers\Abstract\Encoders\AbstractEncoder;
|
use Intervention\Image\Drivers\DriverEncoder;
|
||||||
use Intervention\Image\EncodedImage;
|
use Intervention\Image\EncodedImage;
|
||||||
use Intervention\Image\Interfaces\EncoderInterface;
|
|
||||||
use Intervention\Image\Interfaces\ImageInterface;
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
|
|
||||||
class JpegEncoder extends AbstractEncoder implements EncoderInterface
|
class JpegEncoder extends DriverEncoder
|
||||||
{
|
{
|
||||||
public function __construct(int $quality)
|
|
||||||
{
|
|
||||||
$this->quality = $quality;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function encode(ImageInterface $image): EncodedImage
|
public function encode(ImageInterface $image): EncodedImage
|
||||||
{
|
{
|
||||||
$data = $this->getBuffered(function () use ($image) {
|
$gd = $image->core()->native();
|
||||||
imagejpeg($image->frame()->core(), null, $this->quality);
|
$data = $this->getBuffered(function () use ($gd) {
|
||||||
|
imagejpeg($gd, null, $this->quality);
|
||||||
});
|
});
|
||||||
|
|
||||||
return new EncodedImage($data, 'image/jpeg');
|
return new EncodedImage($data, 'image/jpeg');
|
||||||
|
@@ -2,24 +2,19 @@
|
|||||||
|
|
||||||
namespace Intervention\Image\Drivers\Gd\Encoders;
|
namespace Intervention\Image\Drivers\Gd\Encoders;
|
||||||
|
|
||||||
use Intervention\Image\Drivers\Abstract\Encoders\AbstractEncoder;
|
use Intervention\Image\Drivers\DriverEncoder;
|
||||||
use Intervention\Image\Drivers\Gd\Modifiers\LimitColorsModifier;
|
|
||||||
use Intervention\Image\EncodedImage;
|
use Intervention\Image\EncodedImage;
|
||||||
use Intervention\Image\Interfaces\EncoderInterface;
|
|
||||||
use Intervention\Image\Interfaces\ImageInterface;
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
|
use Intervention\Image\Modifiers\LimitColorsModifier;
|
||||||
|
|
||||||
class PngEncoder extends AbstractEncoder implements EncoderInterface
|
class PngEncoder extends DriverEncoder
|
||||||
{
|
{
|
||||||
public function __construct(protected int $color_limit = 0)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
public function encode(ImageInterface $image): EncodedImage
|
public function encode(ImageInterface $image): EncodedImage
|
||||||
{
|
{
|
||||||
$image = $image->modify(new LimitColorsModifier($this->color_limit));
|
$image = $image->modify(new LimitColorsModifier($this->color_limit));
|
||||||
$data = $this->getBuffered(function () use ($image) {
|
$gd = $image->core()->native();
|
||||||
imagepng($image->frame()->core(), null, -1);
|
$data = $this->getBuffered(function () use ($gd) {
|
||||||
|
imagepng($gd, null, -1);
|
||||||
});
|
});
|
||||||
|
|
||||||
return new EncodedImage($data, 'image/png');
|
return new EncodedImage($data, 'image/png');
|
||||||
|
@@ -2,22 +2,17 @@
|
|||||||
|
|
||||||
namespace Intervention\Image\Drivers\Gd\Encoders;
|
namespace Intervention\Image\Drivers\Gd\Encoders;
|
||||||
|
|
||||||
use Intervention\Image\Drivers\Abstract\Encoders\AbstractEncoder;
|
use Intervention\Image\Drivers\DriverEncoder;
|
||||||
use Intervention\Image\EncodedImage;
|
use Intervention\Image\EncodedImage;
|
||||||
use Intervention\Image\Interfaces\EncoderInterface;
|
|
||||||
use Intervention\Image\Interfaces\ImageInterface;
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
|
|
||||||
class WebpEncoder extends AbstractEncoder implements EncoderInterface
|
class WebpEncoder extends DriverEncoder
|
||||||
{
|
{
|
||||||
public function __construct(int $quality)
|
|
||||||
{
|
|
||||||
$this->quality = $quality;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function encode(ImageInterface $image): EncodedImage
|
public function encode(ImageInterface $image): EncodedImage
|
||||||
{
|
{
|
||||||
$data = $this->getBuffered(function () use ($image) {
|
$gd = $image->core()->native();
|
||||||
imagewebp($image->frame()->core(), null, $this->quality);
|
$data = $this->getBuffered(function () use ($gd) {
|
||||||
|
imagewebp($gd, null, $this->quality);
|
||||||
});
|
});
|
||||||
|
|
||||||
return new EncodedImage($data, 'image/webp');
|
return new EncodedImage($data, 'image/webp');
|
||||||
|
@@ -12,7 +12,7 @@ use Intervention\Image\Interfaces\FactoryInterface;
|
|||||||
use Intervention\Image\Interfaces\ImageInterface;
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
use Intervention\Image\Traits\CanHandleInput;
|
use Intervention\Image\Traits\CanHandleInput;
|
||||||
|
|
||||||
class Factory implements FactoryInterface
|
class DELETE___Factory implements FactoryInterface
|
||||||
{
|
{
|
||||||
use CanHandleInput;
|
use CanHandleInput;
|
||||||
use CanHandleColors;
|
use CanHandleColors;
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
namespace Intervention\Image\Drivers\Gd;
|
namespace Intervention\Image\Drivers\Gd;
|
||||||
|
|
||||||
use Intervention\Image\Drivers\Abstract\AbstractFont;
|
use Intervention\Image\Drivers\AbstractFont;
|
||||||
use Intervention\Image\Geometry\Point;
|
use Intervention\Image\Geometry\Point;
|
||||||
use Intervention\Image\Geometry\Polygon;
|
use Intervention\Image\Geometry\Polygon;
|
||||||
use Intervention\Image\Geometry\Rectangle;
|
use Intervention\Image\Geometry\Rectangle;
|
||||||
|
@@ -3,8 +3,9 @@
|
|||||||
namespace Intervention\Image\Drivers\Gd;
|
namespace Intervention\Image\Drivers\Gd;
|
||||||
|
|
||||||
use GdImage;
|
use GdImage;
|
||||||
use Intervention\Image\Collection;
|
|
||||||
use Intervention\Image\Geometry\Rectangle;
|
use Intervention\Image\Geometry\Rectangle;
|
||||||
|
use Intervention\Image\Image;
|
||||||
|
use Intervention\Image\Interfaces\DriverInterface;
|
||||||
use Intervention\Image\Interfaces\FrameInterface;
|
use Intervention\Image\Interfaces\FrameInterface;
|
||||||
use Intervention\Image\Interfaces\ImageInterface;
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
use Intervention\Image\Interfaces\SizeInterface;
|
use Intervention\Image\Interfaces\SizeInterface;
|
||||||
@@ -12,7 +13,7 @@ use Intervention\Image\Interfaces\SizeInterface;
|
|||||||
class Frame implements FrameInterface
|
class Frame implements FrameInterface
|
||||||
{
|
{
|
||||||
public function __construct(
|
public function __construct(
|
||||||
protected GdImage $core,
|
protected GdImage $data,
|
||||||
protected float $delay = 0,
|
protected float $delay = 0,
|
||||||
protected int $dispose = 1,
|
protected int $dispose = 1,
|
||||||
protected int $offset_left = 0,
|
protected int $offset_left = 0,
|
||||||
@@ -21,26 +22,31 @@ class Frame implements FrameInterface
|
|||||||
//
|
//
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setCore($core): FrameInterface
|
public function toImage(DriverInterface $driver): ImageInterface
|
||||||
{
|
{
|
||||||
$this->core = $core;
|
return new Image($driver, new Core([$this]));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setData($data): FrameInterface
|
||||||
|
{
|
||||||
|
$this->data = $data;
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function core(): GdImage
|
public function data(): GdImage
|
||||||
{
|
{
|
||||||
return $this->core;
|
return $this->data;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function unsetCore(): void
|
public function unsetData(): void
|
||||||
{
|
{
|
||||||
unset($this->core);
|
unset($this->data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function size(): SizeInterface
|
public function size(): SizeInterface
|
||||||
{
|
{
|
||||||
return new Rectangle(imagesx($this->core), imagesy($this->core));
|
return new Rectangle(imagesx($this->data), imagesy($this->data));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function delay(): float
|
public function delay(): float
|
||||||
@@ -98,9 +104,4 @@ class Frame implements FrameInterface
|
|||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function toImage(): ImageInterface
|
|
||||||
{
|
|
||||||
return new Image(new Collection([$this]));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -19,7 +19,7 @@ use Intervention\Image\Resolution;
|
|||||||
use IteratorAggregate;
|
use IteratorAggregate;
|
||||||
use Traversable;
|
use Traversable;
|
||||||
|
|
||||||
class Image extends AbstractImage implements ImageInterface, IteratorAggregate
|
class DELETE__Image extends AbstractImage implements ImageInterface, IteratorAggregate
|
||||||
{
|
{
|
||||||
use CanHandleColors;
|
use CanHandleColors;
|
||||||
|
|
||||||
|
@@ -7,7 +7,7 @@ use Intervention\Image\Colors\Rgb\Decoders\StringColorDecoder as RgbStringColorD
|
|||||||
use Intervention\Image\Colors\Rgb\Decoders\HtmlColornameDecoder;
|
use Intervention\Image\Colors\Rgb\Decoders\HtmlColornameDecoder;
|
||||||
use Intervention\Image\Colors\Rgb\Decoders\TransparentColorDecoder;
|
use Intervention\Image\Colors\Rgb\Decoders\TransparentColorDecoder;
|
||||||
use Intervention\Image\Colors\Cmyk\Decoders\StringColorDecoder as CmykStringColorDecoder;
|
use Intervention\Image\Colors\Cmyk\Decoders\StringColorDecoder as CmykStringColorDecoder;
|
||||||
use Intervention\Image\Drivers\Abstract\AbstractInputHandler;
|
use Intervention\Image\Drivers\AbstractInputHandler;
|
||||||
use Intervention\Image\Drivers\Gd\Decoders\ImageObjectDecoder;
|
use Intervention\Image\Drivers\Gd\Decoders\ImageObjectDecoder;
|
||||||
use Intervention\Image\Drivers\Gd\Decoders\ColorObjectDecoder;
|
use Intervention\Image\Drivers\Gd\Decoders\ColorObjectDecoder;
|
||||||
use Intervention\Image\Drivers\Gd\Decoders\FilePointerImageDecoder;
|
use Intervention\Image\Drivers\Gd\Decoders\FilePointerImageDecoder;
|
||||||
|
@@ -2,30 +2,19 @@
|
|||||||
|
|
||||||
namespace Intervention\Image\Drivers\Gd\Modifiers;
|
namespace Intervention\Image\Drivers\Gd\Modifiers;
|
||||||
|
|
||||||
use Intervention\Image\Interfaces\FrameInterface;
|
use Intervention\Image\Drivers\DriverModifier;
|
||||||
use Intervention\Image\Interfaces\ImageInterface;
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
use Intervention\Image\Interfaces\ModifierInterface;
|
|
||||||
|
|
||||||
class BlurModifier implements ModifierInterface
|
class BlurModifier extends DriverModifier
|
||||||
{
|
{
|
||||||
public function __construct(protected int $amount)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
public function apply(ImageInterface $image): ImageInterface
|
public function apply(ImageInterface $image): ImageInterface
|
||||||
{
|
{
|
||||||
foreach ($image as $frame) {
|
foreach ($image as $frame) {
|
||||||
$this->blurFrame($frame);
|
for ($i = 0; $i < $this->amount; $i++) {
|
||||||
|
imagefilter($frame->data(), IMG_FILTER_GAUSSIAN_BLUR);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $image;
|
return $image;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function blurFrame(FrameInterface $frame): void
|
|
||||||
{
|
|
||||||
for ($i = 0; $i < $this->amount; $i++) {
|
|
||||||
imagefilter($frame->core(), IMG_FILTER_GAUSSIAN_BLUR);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -2,20 +2,15 @@
|
|||||||
|
|
||||||
namespace Intervention\Image\Drivers\Gd\Modifiers;
|
namespace Intervention\Image\Drivers\Gd\Modifiers;
|
||||||
|
|
||||||
|
use Intervention\Image\Drivers\DriverModifier;
|
||||||
use Intervention\Image\Interfaces\ImageInterface;
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
use Intervention\Image\Interfaces\ModifierInterface;
|
|
||||||
|
|
||||||
class BrightnessModifier implements ModifierInterface
|
class BrightnessModifier extends DriverModifier
|
||||||
{
|
{
|
||||||
public function __construct(protected int $level)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
public function apply(ImageInterface $image): ImageInterface
|
public function apply(ImageInterface $image): ImageInterface
|
||||||
{
|
{
|
||||||
foreach ($image as $frame) {
|
foreach ($image as $frame) {
|
||||||
imagefilter($frame->core(), IMG_FILTER_BRIGHTNESS, intval($this->level * 2.55));
|
imagefilter($frame->data(), IMG_FILTER_BRIGHTNESS, intval($this->level * 2.55));
|
||||||
}
|
}
|
||||||
|
|
||||||
return $image;
|
return $image;
|
||||||
|
@@ -2,19 +2,11 @@
|
|||||||
|
|
||||||
namespace Intervention\Image\Drivers\Gd\Modifiers;
|
namespace Intervention\Image\Drivers\Gd\Modifiers;
|
||||||
|
|
||||||
|
use Intervention\Image\Drivers\DriverModifier;
|
||||||
use Intervention\Image\Interfaces\ImageInterface;
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
use Intervention\Image\Interfaces\ModifierInterface;
|
|
||||||
|
|
||||||
class ColorizeModifier implements ModifierInterface
|
class ColorizeModifier extends DriverModifier
|
||||||
{
|
{
|
||||||
public function __construct(
|
|
||||||
protected int $red = 0,
|
|
||||||
protected int $green = 0,
|
|
||||||
protected int $blue = 0
|
|
||||||
) {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
public function apply(ImageInterface $image): ImageInterface
|
public function apply(ImageInterface $image): ImageInterface
|
||||||
{
|
{
|
||||||
// normalize colorize levels
|
// normalize colorize levels
|
||||||
@@ -23,7 +15,7 @@ class ColorizeModifier implements ModifierInterface
|
|||||||
$blue = round($this->blue * 2.55);
|
$blue = round($this->blue * 2.55);
|
||||||
|
|
||||||
foreach ($image as $frame) {
|
foreach ($image as $frame) {
|
||||||
imagefilter($frame->core(), IMG_FILTER_COLORIZE, $red, $green, $blue);
|
imagefilter($frame->data(), IMG_FILTER_COLORIZE, $red, $green, $blue);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $image;
|
return $image;
|
||||||
|
22
src/Drivers/Gd/Modifiers/ColorspaceModifier.php
Normal file
22
src/Drivers/Gd/Modifiers/ColorspaceModifier.php
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Intervention\Image\Drivers\Gd\Modifiers;
|
||||||
|
|
||||||
|
use Intervention\Image\Colors\Rgb\Colorspace as RgbColorspace;
|
||||||
|
use Intervention\Image\Drivers\DriverModifier;
|
||||||
|
use Intervention\Image\Exceptions\NotSupportedException;
|
||||||
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
|
|
||||||
|
class ColorspaceModifier extends DriverModifier
|
||||||
|
{
|
||||||
|
public function apply(ImageInterface $image): ImageInterface
|
||||||
|
{
|
||||||
|
if (!is_a($this->targetColorspace(), RgbColorspace::class)) {
|
||||||
|
throw new NotSupportedException(
|
||||||
|
'Only RGB colorspace is supported with GD driver.'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $image;
|
||||||
|
}
|
||||||
|
}
|
@@ -2,20 +2,15 @@
|
|||||||
|
|
||||||
namespace Intervention\Image\Drivers\Gd\Modifiers;
|
namespace Intervention\Image\Drivers\Gd\Modifiers;
|
||||||
|
|
||||||
|
use Intervention\Image\Drivers\DriverModifier;
|
||||||
use Intervention\Image\Interfaces\ImageInterface;
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
use Intervention\Image\Interfaces\ModifierInterface;
|
|
||||||
|
|
||||||
class ContrastModifier implements ModifierInterface
|
class ContrastModifier extends DriverModifier
|
||||||
{
|
{
|
||||||
public function __construct(protected int $level)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
public function apply(ImageInterface $image): ImageInterface
|
public function apply(ImageInterface $image): ImageInterface
|
||||||
{
|
{
|
||||||
foreach ($image as $frame) {
|
foreach ($image as $frame) {
|
||||||
imagefilter($frame->core(), IMG_FILTER_CONTRAST, ($this->level * -1));
|
imagefilter($frame->data(), IMG_FILTER_CONTRAST, ($this->level * -1));
|
||||||
}
|
}
|
||||||
|
|
||||||
return $image;
|
return $image;
|
||||||
|
@@ -2,32 +2,16 @@
|
|||||||
|
|
||||||
namespace Intervention\Image\Drivers\Gd\Modifiers;
|
namespace Intervention\Image\Drivers\Gd\Modifiers;
|
||||||
|
|
||||||
use Intervention\Image\Geometry\Rectangle;
|
use Intervention\Image\Drivers\DriverModifier;
|
||||||
use Intervention\Image\Interfaces\FrameInterface;
|
use Intervention\Image\Interfaces\FrameInterface;
|
||||||
use Intervention\Image\Interfaces\ImageInterface;
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
use Intervention\Image\Interfaces\ModifierInterface;
|
|
||||||
use Intervention\Image\Interfaces\SizeInterface;
|
use Intervention\Image\Interfaces\SizeInterface;
|
||||||
use Intervention\Image\Traits\CanBuildNewImage;
|
|
||||||
|
|
||||||
class CropModifier implements ModifierInterface
|
class CropModifier extends DriverModifier
|
||||||
{
|
{
|
||||||
use CanBuildNewImage;
|
|
||||||
|
|
||||||
public function __construct(
|
|
||||||
protected int $width,
|
|
||||||
protected int $height,
|
|
||||||
protected int $offset_x = 0,
|
|
||||||
protected int $offset_y = 0,
|
|
||||||
protected string $position = 'top-left'
|
|
||||||
) {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
public function apply(ImageInterface $image): ImageInterface
|
public function apply(ImageInterface $image): ImageInterface
|
||||||
{
|
{
|
||||||
$crop = new Rectangle($this->width, $this->height);
|
$crop = $this->crop($image);
|
||||||
$crop->align($this->position);
|
|
||||||
$crop->alignPivotTo($image->size(), $this->position);
|
|
||||||
|
|
||||||
foreach ($image as $frame) {
|
foreach ($image as $frame) {
|
||||||
$this->cropFrame($frame, $crop);
|
$this->cropFrame($frame, $crop);
|
||||||
@@ -39,13 +23,13 @@ class CropModifier implements ModifierInterface
|
|||||||
protected function cropFrame(FrameInterface $frame, SizeInterface $resizeTo): void
|
protected function cropFrame(FrameInterface $frame, SizeInterface $resizeTo): void
|
||||||
{
|
{
|
||||||
// create new image
|
// create new image
|
||||||
$modified = $this->imageFactory()->newCore(
|
$modified = $this->driver()
|
||||||
$resizeTo->width(),
|
->createImage($resizeTo->width(), $resizeTo->height())
|
||||||
$resizeTo->height()
|
->core()
|
||||||
);
|
->native();
|
||||||
|
|
||||||
// get original image
|
// get original image
|
||||||
$original = $frame->core();
|
$original = $frame->data();
|
||||||
|
|
||||||
// preserve transparency
|
// preserve transparency
|
||||||
$transIndex = imagecolortransparent($original);
|
$transIndex = imagecolortransparent($original);
|
||||||
@@ -72,6 +56,6 @@ class CropModifier implements ModifierInterface
|
|||||||
);
|
);
|
||||||
|
|
||||||
// set new content as recource
|
// set new content as recource
|
||||||
$frame->setCore($modified);
|
$frame->setData($modified);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,18 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Intervention\Image\Drivers\Gd\Modifiers;
|
|
||||||
|
|
||||||
use Intervention\Image\Interfaces\ImageInterface;
|
|
||||||
use Intervention\Image\Interfaces\ModifierInterface;
|
|
||||||
|
|
||||||
class DestroyModifier implements ModifierInterface
|
|
||||||
{
|
|
||||||
public function apply(ImageInterface $image): ImageInterface
|
|
||||||
{
|
|
||||||
foreach ($image as $frame) {
|
|
||||||
$frame->unsetCore();
|
|
||||||
}
|
|
||||||
|
|
||||||
return $image;
|
|
||||||
}
|
|
||||||
}
|
|
@@ -2,55 +2,65 @@
|
|||||||
|
|
||||||
namespace Intervention\Image\Drivers\Gd\Modifiers;
|
namespace Intervention\Image\Drivers\Gd\Modifiers;
|
||||||
|
|
||||||
use Intervention\Image\Drivers\Abstract\Modifiers\AbstractDrawModifier;
|
use Intervention\Image\Drivers\DrawModifier;
|
||||||
use Intervention\Image\Drivers\Gd\Traits\CanHandleColors;
|
|
||||||
use Intervention\Image\Interfaces\ImageInterface;
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
use Intervention\Image\Interfaces\ModifierInterface;
|
|
||||||
|
|
||||||
class DrawEllipseModifier extends AbstractDrawModifier implements ModifierInterface
|
class DrawEllipseModifier extends DrawModifier
|
||||||
{
|
{
|
||||||
use CanHandleColors;
|
|
||||||
|
|
||||||
public function apply(ImageInterface $image): ImageInterface
|
public function apply(ImageInterface $image): ImageInterface
|
||||||
{
|
{
|
||||||
return $image->mapFrames(function ($frame) {
|
foreach ($image as $frame) {
|
||||||
if ($this->ellipse()->hasBorder()) {
|
if ($this->drawable->hasBorder()) {
|
||||||
// slightly smaller ellipse to keep 1px bordered edges clean
|
// slightly smaller ellipse to keep 1px bordered edges clean
|
||||||
if ($this->ellipse()->hasBackgroundColor()) {
|
if ($this->drawable->hasBackgroundColor()) {
|
||||||
imagefilledellipse(
|
imagefilledellipse(
|
||||||
$frame->core(),
|
$frame->data(),
|
||||||
$this->position->x(),
|
$this->position()->x(),
|
||||||
$this->position->y(),
|
$this->position()->y(),
|
||||||
$this->ellipse()->getWidth() - 1,
|
$this->drawable->width() - 1,
|
||||||
$this->ellipse()->getHeight() - 1,
|
$this->drawable->height() - 1,
|
||||||
$this->colorToInteger($this->getBackgroundColor())
|
$this->driver()->colorToNative(
|
||||||
|
$this->backgroundColor(),
|
||||||
|
$image->colorspace()
|
||||||
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
imagesetthickness($frame->core(), $this->ellipse()->getBorderSize());
|
// gd's imageellipse ignores imagesetthickness
|
||||||
|
// so i use imagearc with 360 degrees instead.
|
||||||
|
imagesetthickness(
|
||||||
|
$frame->data(),
|
||||||
|
$this->drawable->borderSize(),
|
||||||
|
);
|
||||||
|
|
||||||
// gd's imageellipse ignores imagesetthickness so i use
|
|
||||||
// imagearc with 360 degrees instead.
|
|
||||||
imagearc(
|
imagearc(
|
||||||
$frame->core(),
|
$frame->data(),
|
||||||
$this->position->x(),
|
$this->position()->x(),
|
||||||
$this->position->y(),
|
$this->position()->y(),
|
||||||
$this->ellipse()->getWidth(),
|
$this->drawable->width(),
|
||||||
$this->ellipse()->getHeight(),
|
$this->drawable->height(),
|
||||||
0,
|
0,
|
||||||
360,
|
360,
|
||||||
$this->colorToInteger($this->getBorderColor())
|
$this->driver()->colorToNative(
|
||||||
|
$this->borderColor(),
|
||||||
|
$image->colorspace()
|
||||||
|
)
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
imagefilledellipse(
|
imagefilledellipse(
|
||||||
$frame->core(),
|
$frame->data(),
|
||||||
$this->position->x(),
|
$this->position()->x(),
|
||||||
$this->position->y(),
|
$this->position()->y(),
|
||||||
$this->ellipse()->getWidth(),
|
$this->drawable->width(),
|
||||||
$this->ellipse()->getHeight(),
|
$this->drawable->height(),
|
||||||
$this->colorToInteger($this->getBackgroundColor())
|
$this->driver()->colorToNative(
|
||||||
|
$this->backgroundColor(),
|
||||||
|
$image->colorspace()
|
||||||
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
|
||||||
|
return $image;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -2,26 +2,27 @@
|
|||||||
|
|
||||||
namespace Intervention\Image\Drivers\Gd\Modifiers;
|
namespace Intervention\Image\Drivers\Gd\Modifiers;
|
||||||
|
|
||||||
use Intervention\Image\Drivers\Abstract\Modifiers\AbstractDrawModifier;
|
use Intervention\Image\Drivers\DrawModifier;
|
||||||
use Intervention\Image\Drivers\Gd\Traits\CanHandleColors;
|
|
||||||
use Intervention\Image\Interfaces\ImageInterface;
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
use Intervention\Image\Interfaces\ModifierInterface;
|
|
||||||
|
|
||||||
class DrawLineModifier extends AbstractDrawModifier implements ModifierInterface
|
class DrawLineModifier extends DrawModifier
|
||||||
{
|
{
|
||||||
use CanHandleColors;
|
|
||||||
|
|
||||||
public function apply(ImageInterface $image): ImageInterface
|
public function apply(ImageInterface $image): ImageInterface
|
||||||
{
|
{
|
||||||
return $image->mapFrames(function ($frame) {
|
foreach ($image as $frame) {
|
||||||
imageline(
|
imageline(
|
||||||
$frame->core(),
|
$frame->data(),
|
||||||
$this->line()->getStart()->x(),
|
$this->drawable->getStart()->x(),
|
||||||
$this->line()->getStart()->y(),
|
$this->drawable->getStart()->y(),
|
||||||
$this->line()->getEnd()->x(),
|
$this->drawable->getEnd()->x(),
|
||||||
$this->line()->getEnd()->y(),
|
$this->drawable->getEnd()->y(),
|
||||||
$this->colorToInteger($this->getBackgroundColor())
|
$this->driver()->colorToNative(
|
||||||
|
$this->backgroundColor(),
|
||||||
|
$image->colorspace()
|
||||||
|
)
|
||||||
);
|
);
|
||||||
});
|
}
|
||||||
|
|
||||||
|
return $image;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -2,34 +2,27 @@
|
|||||||
|
|
||||||
namespace Intervention\Image\Drivers\Gd\Modifiers;
|
namespace Intervention\Image\Drivers\Gd\Modifiers;
|
||||||
|
|
||||||
use Intervention\Image\Drivers\Gd\Traits\CanHandleColors;
|
use Intervention\Image\Drivers\DriverModifier;
|
||||||
use Intervention\Image\Geometry\Point;
|
|
||||||
use Intervention\Image\Interfaces\ImageInterface;
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
use Intervention\Image\Interfaces\ModifierInterface;
|
|
||||||
use Intervention\Image\Traits\CanHandleInput;
|
|
||||||
|
|
||||||
class DrawPixelModifier implements ModifierInterface
|
class DrawPixelModifier extends DriverModifier
|
||||||
{
|
{
|
||||||
use CanHandleInput;
|
|
||||||
use CanHandleColors;
|
|
||||||
|
|
||||||
public function __construct(
|
|
||||||
protected Point $position,
|
|
||||||
protected $color
|
|
||||||
) {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
public function apply(ImageInterface $image): ImageInterface
|
public function apply(ImageInterface $image): ImageInterface
|
||||||
{
|
{
|
||||||
$color = $this->handleInput($this->color);
|
$color = $this->driver()->colorToNative(
|
||||||
return $image->mapFrames(function ($frame) use ($color) {
|
$this->driver()->handleInput($this->color),
|
||||||
|
$image->colorspace()
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ($image as $frame) {
|
||||||
imagesetpixel(
|
imagesetpixel(
|
||||||
$frame->core(),
|
$frame->data(),
|
||||||
$this->position->x(),
|
$this->position->x(),
|
||||||
$this->position->y(),
|
$this->position->y(),
|
||||||
$this->colorToInteger($color)
|
$color
|
||||||
);
|
);
|
||||||
});
|
}
|
||||||
|
|
||||||
|
return $image;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -2,42 +2,38 @@
|
|||||||
|
|
||||||
namespace Intervention\Image\Drivers\Gd\Modifiers;
|
namespace Intervention\Image\Drivers\Gd\Modifiers;
|
||||||
|
|
||||||
use Intervention\Image\Drivers\Abstract\Modifiers\AbstractDrawModifier;
|
use Intervention\Image\Drivers\DrawModifier;
|
||||||
use Intervention\Image\Drivers\Gd\Traits\CanHandleColors;
|
|
||||||
use Intervention\Image\Interfaces\DrawableInterface;
|
|
||||||
use Intervention\Image\Interfaces\ImageInterface;
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
use Intervention\Image\Interfaces\ModifierInterface;
|
|
||||||
|
|
||||||
class DrawPolygonModifier extends AbstractDrawModifier implements ModifierInterface
|
class DrawPolygonModifier extends DrawModifier
|
||||||
{
|
{
|
||||||
use CanHandleColors;
|
|
||||||
|
|
||||||
public function __construct(
|
|
||||||
protected DrawableInterface $drawable
|
|
||||||
) {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
public function apply(ImageInterface $image): ImageInterface
|
public function apply(ImageInterface $image): ImageInterface
|
||||||
{
|
{
|
||||||
return $image->mapFrames(function ($frame) {
|
foreach ($image as $frame) {
|
||||||
if ($this->polygon()->hasBackgroundColor()) {
|
if ($this->drawable->hasBackgroundColor()) {
|
||||||
imagefilledpolygon(
|
imagefilledpolygon(
|
||||||
$frame->core(),
|
$frame->data(),
|
||||||
$this->polygon()->toArray(),
|
$this->drawable->toArray(),
|
||||||
$this->colorToInteger($this->getBackgroundColor())
|
$this->driver()->colorToNative(
|
||||||
|
$this->backgroundColor(),
|
||||||
|
$image->colorspace()
|
||||||
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->polygon()->hasBorder()) {
|
if ($this->drawable->hasBorder()) {
|
||||||
imagesetthickness($frame->core(), $this->polygon()->getBorderSize());
|
imagesetthickness($frame->data(), $this->drawable->borderSize());
|
||||||
imagepolygon(
|
imagepolygon(
|
||||||
$frame->core(),
|
$frame->data(),
|
||||||
$this->polygon()->toArray(),
|
$this->drawable->toArray(),
|
||||||
$this->polygon()->count(),
|
$this->driver()->colorToNative(
|
||||||
$this->colorToInteger($this->getBorderColor())
|
$this->borderColor(),
|
||||||
|
$image->colorspace()
|
||||||
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
|
||||||
|
return $image;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -2,43 +2,45 @@
|
|||||||
|
|
||||||
namespace Intervention\Image\Drivers\Gd\Modifiers;
|
namespace Intervention\Image\Drivers\Gd\Modifiers;
|
||||||
|
|
||||||
use Intervention\Image\Drivers\Abstract\Modifiers\AbstractDrawModifier;
|
use Intervention\Image\Drivers\DrawModifier;
|
||||||
use Intervention\Image\Drivers\Gd\Traits\CanHandleColors;
|
|
||||||
use Intervention\Image\Interfaces\ImageInterface;
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
use Intervention\Image\Interfaces\ModifierInterface;
|
|
||||||
|
|
||||||
class DrawRectangleModifier extends AbstractDrawModifier implements ModifierInterface
|
class DrawRectangleModifier extends DrawModifier
|
||||||
{
|
{
|
||||||
use CanHandleColors;
|
|
||||||
|
|
||||||
public function apply(ImageInterface $image): ImageInterface
|
public function apply(ImageInterface $image): ImageInterface
|
||||||
{
|
{
|
||||||
$image->mapFrames(function ($frame) {
|
foreach ($image as $frame) {
|
||||||
// draw background
|
// draw background
|
||||||
if ($this->rectangle()->hasBackgroundColor()) {
|
if ($this->drawable->hasBackgroundColor()) {
|
||||||
imagefilledrectangle(
|
imagefilledrectangle(
|
||||||
$frame->core(),
|
$frame->data(),
|
||||||
$this->position->x(),
|
$this->position->x(),
|
||||||
$this->position->y(),
|
$this->position->y(),
|
||||||
$this->position->x() + $this->rectangle()->bottomRightPoint()->x(),
|
$this->position->x() + $this->drawable->width(),
|
||||||
$this->position->y() + $this->rectangle()->bottomRightPoint()->y(),
|
$this->position->y() + $this->drawable->height(),
|
||||||
$this->colorToInteger($this->getBackgroundColor())
|
$this->driver()->colorToNative(
|
||||||
|
$this->backgroundColor(),
|
||||||
|
$image->colorspace()
|
||||||
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->rectangle()->hasBorder()) {
|
// draw border
|
||||||
// draw border
|
if ($this->drawable->hasBorder()) {
|
||||||
imagesetthickness($frame->core(), $this->rectangle()->getBorderSize());
|
imagesetthickness($frame->data(), $this->drawable->borderSize());
|
||||||
imagerectangle(
|
imagerectangle(
|
||||||
$frame->core(),
|
$frame->data(),
|
||||||
$this->position->x(),
|
$this->position->x(),
|
||||||
$this->position->y(),
|
$this->position->y(),
|
||||||
$this->position->x() + $this->rectangle()->bottomRightPoint()->x(),
|
$this->position->x() + $this->drawable->width(),
|
||||||
$this->position->y() + $this->rectangle()->bottomRightPoint()->y(),
|
$this->position->y() + $this->drawable->height(),
|
||||||
$this->colorToInteger($this->getBorderColor())
|
$this->driver()->colorToNative(
|
||||||
|
$this->borderColor(),
|
||||||
|
$image->colorspace()
|
||||||
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
|
||||||
return $image;
|
return $image;
|
||||||
}
|
}
|
||||||
|
@@ -2,25 +2,16 @@
|
|||||||
|
|
||||||
namespace Intervention\Image\Drivers\Gd\Modifiers;
|
namespace Intervention\Image\Drivers\Gd\Modifiers;
|
||||||
|
|
||||||
|
use Intervention\Image\Colors\Rgb\Colorspace;
|
||||||
|
use Intervention\Image\Drivers\DriverModifier;
|
||||||
use Intervention\Image\Drivers\Gd\Frame;
|
use Intervention\Image\Drivers\Gd\Frame;
|
||||||
use Intervention\Image\Drivers\Gd\Traits\CanHandleColors;
|
|
||||||
use Intervention\Image\Geometry\Point;
|
|
||||||
use Intervention\Image\Interfaces\ColorInterface;
|
|
||||||
use Intervention\Image\Interfaces\ImageInterface;
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
use Intervention\Image\Interfaces\ModifierInterface;
|
|
||||||
|
|
||||||
class FillModifier implements ModifierInterface
|
class FillModifier extends DriverModifier
|
||||||
{
|
{
|
||||||
use CanHandleColors;
|
|
||||||
|
|
||||||
public function __construct(protected ColorInterface $color, protected ?Point $position = null)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
public function apply(ImageInterface $image): ImageInterface
|
public function apply(ImageInterface $image): ImageInterface
|
||||||
{
|
{
|
||||||
$color = $this->colorToInteger($this->color);
|
$color = $this->color();
|
||||||
|
|
||||||
foreach ($image as $frame) {
|
foreach ($image as $frame) {
|
||||||
if ($this->hasPosition()) {
|
if ($this->hasPosition()) {
|
||||||
@@ -33,21 +24,29 @@ class FillModifier implements ModifierInterface
|
|||||||
return $image;
|
return $image;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function floodFillWithColor(Frame $frame, int $color): void
|
private function color(): int
|
||||||
|
{
|
||||||
|
return $this->driver()->colorToNative(
|
||||||
|
$this->driver()->handleInput($this->color),
|
||||||
|
new Colorspace()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function floodFillWithColor(Frame $frame, int $color): void
|
||||||
{
|
{
|
||||||
imagefill(
|
imagefill(
|
||||||
$frame->core(),
|
$frame->data(),
|
||||||
$this->position->x(),
|
$this->position->x(),
|
||||||
$this->position->y(),
|
$this->position->y(),
|
||||||
$color
|
$color
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function fillAllWithColor(Frame $frame, int $color): void
|
private function fillAllWithColor(Frame $frame, int $color): void
|
||||||
{
|
{
|
||||||
imagealphablending($frame->core(), true);
|
imagealphablending($frame->data(), true);
|
||||||
imagefilledrectangle(
|
imagefilledrectangle(
|
||||||
$frame->core(),
|
$frame->data(),
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
$frame->size()->width() - 1,
|
$frame->size()->width() - 1,
|
||||||
@@ -55,9 +54,4 @@ class FillModifier implements ModifierInterface
|
|||||||
$color
|
$color
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function hasPosition(): bool
|
|
||||||
{
|
|
||||||
return !empty($this->position);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -6,7 +6,7 @@ use Intervention\Image\Interfaces\SizeInterface;
|
|||||||
|
|
||||||
class FitDownModifier extends FitModifier
|
class FitDownModifier extends FitModifier
|
||||||
{
|
{
|
||||||
protected function getResizeSize(SizeInterface $size): SizeInterface
|
public function getResizeSize(SizeInterface $size): SizeInterface
|
||||||
{
|
{
|
||||||
return $size->scaleDown($this->width, $this->height);
|
return $size->scaleDown($this->width, $this->height);
|
||||||
}
|
}
|
||||||
|
@@ -2,17 +2,13 @@
|
|||||||
|
|
||||||
namespace Intervention\Image\Drivers\Gd\Modifiers;
|
namespace Intervention\Image\Drivers\Gd\Modifiers;
|
||||||
|
|
||||||
use Intervention\Image\Drivers\Abstract\Modifiers\AbstractFitModifier;
|
use Intervention\Image\Drivers\DriverModifier;
|
||||||
use Intervention\Image\Interfaces\FrameInterface;
|
use Intervention\Image\Interfaces\FrameInterface;
|
||||||
use Intervention\Image\Interfaces\ImageInterface;
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
use Intervention\Image\Interfaces\ModifierInterface;
|
|
||||||
use Intervention\Image\Interfaces\SizeInterface;
|
use Intervention\Image\Interfaces\SizeInterface;
|
||||||
use Intervention\Image\Traits\CanBuildNewImage;
|
|
||||||
|
|
||||||
class FitModifier extends AbstractFitModifier implements ModifierInterface
|
class FitModifier extends DriverModifier
|
||||||
{
|
{
|
||||||
use CanBuildNewImage;
|
|
||||||
|
|
||||||
public function apply(ImageInterface $image): ImageInterface
|
public function apply(ImageInterface $image): ImageInterface
|
||||||
{
|
{
|
||||||
$crop = $this->getCropSize($image);
|
$crop = $this->getCropSize($image);
|
||||||
@@ -28,13 +24,13 @@ class FitModifier extends AbstractFitModifier implements ModifierInterface
|
|||||||
protected function modifyFrame(FrameInterface $frame, SizeInterface $crop, SizeInterface $resize): void
|
protected function modifyFrame(FrameInterface $frame, SizeInterface $crop, SizeInterface $resize): void
|
||||||
{
|
{
|
||||||
// create new image
|
// create new image
|
||||||
$modified = $this->imageFactory()->newCore(
|
$modified = $this->driver()->createImage(
|
||||||
$resize->width(),
|
$resize->width(),
|
||||||
$resize->height()
|
$resize->height()
|
||||||
);
|
)->core()->native();
|
||||||
|
|
||||||
// get original image
|
// get original image
|
||||||
$original = $frame->core();
|
$original = $frame->data();
|
||||||
|
|
||||||
// preserve transparency
|
// preserve transparency
|
||||||
$transIndex = imagecolortransparent($original);
|
$transIndex = imagecolortransparent($original);
|
||||||
@@ -61,6 +57,6 @@ class FitModifier extends AbstractFitModifier implements ModifierInterface
|
|||||||
);
|
);
|
||||||
|
|
||||||
// set new content as resource
|
// set new content as resource
|
||||||
$frame->setCore($modified);
|
$frame->setData($modified);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -2,15 +2,15 @@
|
|||||||
|
|
||||||
namespace Intervention\Image\Drivers\Gd\Modifiers;
|
namespace Intervention\Image\Drivers\Gd\Modifiers;
|
||||||
|
|
||||||
|
use Intervention\Image\Drivers\DriverModifier;
|
||||||
use Intervention\Image\Interfaces\ImageInterface;
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
use Intervention\Image\Interfaces\ModifierInterface;
|
|
||||||
|
|
||||||
class FlipModifier implements ModifierInterface
|
class FlipModifier extends DriverModifier
|
||||||
{
|
{
|
||||||
public function apply(ImageInterface $image): ImageInterface
|
public function apply(ImageInterface $image): ImageInterface
|
||||||
{
|
{
|
||||||
foreach ($image as $frame) {
|
foreach ($image as $frame) {
|
||||||
imageflip($frame->core(), IMG_FLIP_VERTICAL);
|
imageflip($frame->data(), IMG_FLIP_VERTICAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $image;
|
return $image;
|
||||||
|
@@ -2,15 +2,15 @@
|
|||||||
|
|
||||||
namespace Intervention\Image\Drivers\Gd\Modifiers;
|
namespace Intervention\Image\Drivers\Gd\Modifiers;
|
||||||
|
|
||||||
|
use Intervention\Image\Drivers\DriverModifier;
|
||||||
use Intervention\Image\Interfaces\ImageInterface;
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
use Intervention\Image\Interfaces\ModifierInterface;
|
|
||||||
|
|
||||||
class FlopModifier implements ModifierInterface
|
class FlopModifier extends DriverModifier
|
||||||
{
|
{
|
||||||
public function apply(ImageInterface $image): ImageInterface
|
public function apply(ImageInterface $image): ImageInterface
|
||||||
{
|
{
|
||||||
foreach ($image as $frame) {
|
foreach ($image as $frame) {
|
||||||
imageflip($frame->core(), IMG_FLIP_HORIZONTAL);
|
imageflip($frame->data(), IMG_FLIP_HORIZONTAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $image;
|
return $image;
|
||||||
|
@@ -2,20 +2,15 @@
|
|||||||
|
|
||||||
namespace Intervention\Image\Drivers\Gd\Modifiers;
|
namespace Intervention\Image\Drivers\Gd\Modifiers;
|
||||||
|
|
||||||
|
use Intervention\Image\Drivers\DriverModifier;
|
||||||
use Intervention\Image\Interfaces\ImageInterface;
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
use Intervention\Image\Interfaces\ModifierInterface;
|
|
||||||
|
|
||||||
class GammaModifier implements ModifierInterface
|
class GammaModifier extends DriverModifier
|
||||||
{
|
{
|
||||||
public function __construct(protected float $gamma)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
public function apply(ImageInterface $image): ImageInterface
|
public function apply(ImageInterface $image): ImageInterface
|
||||||
{
|
{
|
||||||
foreach ($image as $frame) {
|
foreach ($image as $frame) {
|
||||||
imagegammacorrect($frame->core(), 1, $this->gamma);
|
imagegammacorrect($frame->data(), 1, $this->gamma);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $image;
|
return $image;
|
||||||
|
@@ -2,15 +2,15 @@
|
|||||||
|
|
||||||
namespace Intervention\Image\Drivers\Gd\Modifiers;
|
namespace Intervention\Image\Drivers\Gd\Modifiers;
|
||||||
|
|
||||||
|
use Intervention\Image\Drivers\DriverModifier;
|
||||||
use Intervention\Image\Interfaces\ImageInterface;
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
use Intervention\Image\Interfaces\ModifierInterface;
|
|
||||||
|
|
||||||
class GreyscaleModifier implements ModifierInterface
|
class GreyscaleModifier extends DriverModifier
|
||||||
{
|
{
|
||||||
public function apply(ImageInterface $image): ImageInterface
|
public function apply(ImageInterface $image): ImageInterface
|
||||||
{
|
{
|
||||||
foreach ($image as $frame) {
|
foreach ($image as $frame) {
|
||||||
imagefilter($frame->core(), IMG_FILTER_GRAYSCALE);
|
imagefilter($frame->data(), IMG_FILTER_GRAYSCALE);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $image;
|
return $image;
|
||||||
|
@@ -2,15 +2,15 @@
|
|||||||
|
|
||||||
namespace Intervention\Image\Drivers\Gd\Modifiers;
|
namespace Intervention\Image\Drivers\Gd\Modifiers;
|
||||||
|
|
||||||
|
use Intervention\Image\Drivers\DriverModifier;
|
||||||
use Intervention\Image\Interfaces\ImageInterface;
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
use Intervention\Image\Interfaces\ModifierInterface;
|
|
||||||
|
|
||||||
class InvertModifier implements ModifierInterface
|
class InvertModifier extends DriverModifier
|
||||||
{
|
{
|
||||||
public function apply(ImageInterface $image): ImageInterface
|
public function apply(ImageInterface $image): ImageInterface
|
||||||
{
|
{
|
||||||
foreach ($image as $frame) {
|
foreach ($image as $frame) {
|
||||||
imagefilter($frame->core(), IMG_FILTER_NEGATE);
|
imagefilter($frame->data(), IMG_FILTER_NEGATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $image;
|
return $image;
|
||||||
|
@@ -2,16 +2,11 @@
|
|||||||
|
|
||||||
namespace Intervention\Image\Drivers\Gd\Modifiers;
|
namespace Intervention\Image\Drivers\Gd\Modifiers;
|
||||||
|
|
||||||
|
use Intervention\Image\Drivers\DriverModifier;
|
||||||
use Intervention\Image\Interfaces\ImageInterface;
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
use Intervention\Image\Interfaces\ModifierInterface;
|
|
||||||
|
|
||||||
class LimitColorsModifier implements ModifierInterface
|
class LimitColorsModifier extends DriverModifier
|
||||||
{
|
{
|
||||||
public function __construct(protected int $limit = 0, protected int $threshold = 256)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
public function apply(ImageInterface $image): ImageInterface
|
public function apply(ImageInterface $image): ImageInterface
|
||||||
{
|
{
|
||||||
// no color limit: no reduction
|
// no color limit: no reduction
|
||||||
@@ -43,15 +38,15 @@ class LimitColorsModifier implements ModifierInterface
|
|||||||
imagecolortransparent($reduced, $matte);
|
imagecolortransparent($reduced, $matte);
|
||||||
|
|
||||||
// copy original image
|
// copy original image
|
||||||
imagecopy($reduced, $frame->core(), 0, 0, 0, 0, $width, $height);
|
imagecopy($reduced, $frame->data(), 0, 0, 0, 0, $width, $height);
|
||||||
|
|
||||||
// reduce limit by one to include possible transparency in palette
|
// reduce limit by one to include possible transparency in palette
|
||||||
$limit = imagecolortransparent($frame->core()) === -1 ? $this->limit : $this->limit - 1;
|
$limit = imagecolortransparent($frame->data()) === -1 ? $this->limit : $this->limit - 1;
|
||||||
|
|
||||||
// decrease colors
|
// decrease colors
|
||||||
imagetruecolortopalette($reduced, true, $limit);
|
imagetruecolortopalette($reduced, true, $limit);
|
||||||
|
|
||||||
$frame->setCore($reduced);
|
$frame->setData($reduced);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -2,24 +2,6 @@
|
|||||||
|
|
||||||
namespace Intervention\Image\Drivers\Gd\Modifiers;
|
namespace Intervention\Image\Drivers\Gd\Modifiers;
|
||||||
|
|
||||||
use Intervention\Image\Geometry\Rectangle;
|
|
||||||
use Intervention\Image\Interfaces\ImageInterface;
|
|
||||||
use Intervention\Image\Interfaces\SizeInterface;
|
|
||||||
|
|
||||||
class PadDownModifier extends PadModifier
|
class PadDownModifier extends PadModifier
|
||||||
{
|
{
|
||||||
protected function getCropSize(ImageInterface $image): SizeInterface
|
|
||||||
{
|
|
||||||
$resize = $this->getResizeSize($image);
|
|
||||||
|
|
||||||
return $image->size()
|
|
||||||
->contain($resize->width(), $resize->height())
|
|
||||||
->alignPivotTo($resize, $this->position);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function getResizeSize(ImageInterface $image): SizeInterface
|
|
||||||
{
|
|
||||||
return (new Rectangle($this->width, $this->height))
|
|
||||||
->resizeDown($image->width(), $image->height());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -2,27 +2,20 @@
|
|||||||
|
|
||||||
namespace Intervention\Image\Drivers\Gd\Modifiers;
|
namespace Intervention\Image\Drivers\Gd\Modifiers;
|
||||||
|
|
||||||
use Intervention\Image\Drivers\Abstract\Modifiers\AbstractPadModifier;
|
use Intervention\Image\Drivers\DriverModifier;
|
||||||
use Intervention\Image\Drivers\Gd\Traits\CanHandleColors;
|
|
||||||
use Intervention\Image\Interfaces\ColorInterface;
|
use Intervention\Image\Interfaces\ColorInterface;
|
||||||
use Intervention\Image\Interfaces\FrameInterface;
|
use Intervention\Image\Interfaces\FrameInterface;
|
||||||
use Intervention\Image\Interfaces\ImageInterface;
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
use Intervention\Image\Interfaces\ModifierInterface;
|
|
||||||
use Intervention\Image\Interfaces\SizeInterface;
|
use Intervention\Image\Interfaces\SizeInterface;
|
||||||
use Intervention\Image\Traits\CanBuildNewImage;
|
use Intervention\Image\Modifiers\FillModifier;
|
||||||
use Intervention\Image\Traits\CanHandleInput;
|
|
||||||
|
|
||||||
class PadModifier extends AbstractPadModifier implements ModifierInterface
|
class PadModifier extends DriverModifier
|
||||||
{
|
{
|
||||||
use CanHandleInput;
|
|
||||||
use CanHandleColors;
|
|
||||||
use CanBuildNewImage;
|
|
||||||
|
|
||||||
public function apply(ImageInterface $image): ImageInterface
|
public function apply(ImageInterface $image): ImageInterface
|
||||||
{
|
{
|
||||||
$crop = $this->getCropSize($image);
|
$crop = $this->getCropSize($image);
|
||||||
$resize = $this->getResizeSize($image);
|
$resize = $this->getResizeSize($image);
|
||||||
$background = $this->handleInput($this->background);
|
$background = $this->driver()->handleInput($this->background);
|
||||||
|
|
||||||
foreach ($image as $frame) {
|
foreach ($image as $frame) {
|
||||||
$this->modify($frame, $crop, $resize, $background);
|
$this->modify($frame, $crop, $resize, $background);
|
||||||
@@ -38,11 +31,12 @@ class PadModifier extends AbstractPadModifier implements ModifierInterface
|
|||||||
ColorInterface $background
|
ColorInterface $background
|
||||||
): void {
|
): void {
|
||||||
// create new gd image
|
// create new gd image
|
||||||
$modified = $this->imageFactory()->newCore(
|
$modified = $this->driver()->createImage(
|
||||||
$resize->width(),
|
$resize->width(),
|
||||||
$resize->height(),
|
$resize->height()
|
||||||
$background
|
)->modify(
|
||||||
);
|
new FillModifier($background)
|
||||||
|
)->core()->native();
|
||||||
|
|
||||||
// make image area transparent to keep transparency
|
// make image area transparent to keep transparency
|
||||||
// even if background-color is set
|
// even if background-color is set
|
||||||
@@ -62,7 +56,7 @@ class PadModifier extends AbstractPadModifier implements ModifierInterface
|
|||||||
imagealphablending($modified, true);
|
imagealphablending($modified, true);
|
||||||
imagecopyresampled(
|
imagecopyresampled(
|
||||||
$modified,
|
$modified,
|
||||||
$frame->core(),
|
$frame->data(),
|
||||||
$crop->pivot()->x(),
|
$crop->pivot()->x(),
|
||||||
$crop->pivot()->y(),
|
$crop->pivot()->y(),
|
||||||
0,
|
0,
|
||||||
@@ -74,6 +68,6 @@ class PadModifier extends AbstractPadModifier implements ModifierInterface
|
|||||||
);
|
);
|
||||||
|
|
||||||
// set new content as recource
|
// set new content as recource
|
||||||
$frame->setCore($modified);
|
$frame->setData($modified);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -2,21 +2,15 @@
|
|||||||
|
|
||||||
namespace Intervention\Image\Drivers\Gd\Modifiers;
|
namespace Intervention\Image\Drivers\Gd\Modifiers;
|
||||||
|
|
||||||
use Intervention\Image\Interfaces\FrameInterface;
|
use Intervention\Image\Drivers\DriverModifier;
|
||||||
use Intervention\Image\Interfaces\ImageInterface;
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
use Intervention\Image\Interfaces\ModifierInterface;
|
|
||||||
|
|
||||||
class PixelateModifier implements ModifierInterface
|
class PixelateModifier extends DriverModifier
|
||||||
{
|
{
|
||||||
public function __construct(protected int $size)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
public function apply(ImageInterface $image): ImageInterface
|
public function apply(ImageInterface $image): ImageInterface
|
||||||
{
|
{
|
||||||
foreach ($image as $frame) {
|
foreach ($image as $frame) {
|
||||||
imagefilter($frame->core(), IMG_FILTER_PIXELATE, $this->size, true);
|
imagefilter($frame->data(), IMG_FILTER_PIXELATE, $this->size, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $image;
|
return $image;
|
||||||
|
@@ -2,38 +2,21 @@
|
|||||||
|
|
||||||
namespace Intervention\Image\Drivers\Gd\Modifiers;
|
namespace Intervention\Image\Drivers\Gd\Modifiers;
|
||||||
|
|
||||||
|
use Intervention\Image\Drivers\DriverModifier;
|
||||||
use Intervention\Image\Interfaces\ImageInterface;
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
use Intervention\Image\Interfaces\ModifierInterface;
|
|
||||||
use Intervention\Image\Interfaces\PointInterface;
|
|
||||||
use Intervention\Image\Traits\CanHandleInput;
|
|
||||||
|
|
||||||
class PlaceModifier implements ModifierInterface
|
class PlaceModifier extends DriverModifier
|
||||||
{
|
{
|
||||||
use CanHandleInput;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create new modifier
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public function __construct(
|
|
||||||
protected $element,
|
|
||||||
protected string $position,
|
|
||||||
protected int $offset_x,
|
|
||||||
protected int $offset_y
|
|
||||||
) {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
public function apply(ImageInterface $image): ImageInterface
|
public function apply(ImageInterface $image): ImageInterface
|
||||||
{
|
{
|
||||||
$watermark = $this->handleInput($this->element);
|
$watermark = $this->driver()->handleInput($this->element);
|
||||||
$position = $this->getPosition($image, $watermark);
|
$position = $this->getPosition($image, $watermark);
|
||||||
|
|
||||||
foreach ($image as $frame) {
|
foreach ($image as $frame) {
|
||||||
imagealphablending($frame->core(), true);
|
imagealphablending($frame->data(), true);
|
||||||
imagecopy(
|
imagecopy(
|
||||||
$frame->core(),
|
$frame->data(),
|
||||||
$watermark->frame()->core(),
|
$watermark->core()->native(),
|
||||||
$position->x(),
|
$position->x(),
|
||||||
$position->y(),
|
$position->y(),
|
||||||
0,
|
0,
|
||||||
@@ -45,12 +28,4 @@ class PlaceModifier implements ModifierInterface
|
|||||||
|
|
||||||
return $image;
|
return $image;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getPosition(ImageInterface $image, ImageInterface $watermark): PointInterface
|
|
||||||
{
|
|
||||||
$image_size = $image->size()->movePivot($this->position, $this->offset_x, $this->offset_y);
|
|
||||||
$watermark_size = $watermark->size()->movePivot($this->position);
|
|
||||||
|
|
||||||
return $image_size->relativePositionTo($watermark_size);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
17
src/Drivers/Gd/Modifiers/ProfileModifier.php
Normal file
17
src/Drivers/Gd/Modifiers/ProfileModifier.php
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Intervention\Image\Drivers\Imagick\Modifiers;
|
||||||
|
|
||||||
|
use Intervention\Image\Drivers\DriverModifier;
|
||||||
|
use Intervention\Image\Exceptions\NotSupportedException;
|
||||||
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
|
|
||||||
|
class ProfileModifier extends DriverModifier
|
||||||
|
{
|
||||||
|
public function apply(ImageInterface $image): ImageInterface
|
||||||
|
{
|
||||||
|
throw new NotSupportedException(
|
||||||
|
'Color profiles are not supported by GD driver.'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
17
src/Drivers/Gd/Modifiers/ProfileRemovalModifier.php
Normal file
17
src/Drivers/Gd/Modifiers/ProfileRemovalModifier.php
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Intervention\Image\Drivers\Gd\Modifiers;
|
||||||
|
|
||||||
|
use Intervention\Image\Drivers\DriverModifier;
|
||||||
|
use Intervention\Image\Exceptions\NotSupportedException;
|
||||||
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
|
|
||||||
|
class ProfileRemovalModifier extends DriverModifier
|
||||||
|
{
|
||||||
|
public function apply(ImageInterface $image): ImageInterface
|
||||||
|
{
|
||||||
|
throw new NotSupportedException(
|
||||||
|
'Color profiles are not supported by GD driver.'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@@ -2,26 +2,21 @@
|
|||||||
|
|
||||||
namespace Intervention\Image\Drivers\Gd\Modifiers;
|
namespace Intervention\Image\Drivers\Gd\Modifiers;
|
||||||
|
|
||||||
use Intervention\Image\Collection;
|
use Intervention\Image\Drivers\DriverModifier;
|
||||||
use Intervention\Image\Drivers\Abstract\Modifiers\AbstractRemoveAnimationModifier;
|
use Intervention\Image\Drivers\Gd\Core;
|
||||||
|
use Intervention\Image\Image;
|
||||||
use Intervention\Image\Interfaces\ImageInterface;
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
use Intervention\Image\Traits\CanCheckType;
|
|
||||||
use Intervention\Image\Drivers\Gd\Image;
|
|
||||||
|
|
||||||
class RemoveAnimationModifier extends AbstractRemoveAnimationModifier
|
class RemoveAnimationModifier extends DriverModifier
|
||||||
{
|
{
|
||||||
use CanCheckType;
|
|
||||||
|
|
||||||
public function __construct(protected int|string $position = 0)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
public function apply(ImageInterface $image): ImageInterface
|
public function apply(ImageInterface $image): ImageInterface
|
||||||
{
|
{
|
||||||
$image = $this->failIfNotClass($image, Image::class);
|
return new Image(
|
||||||
return $image->setFrames(new Collection([
|
$image->driver(),
|
||||||
$this->chosenFrame($image, $this->position)
|
new Core([
|
||||||
]));
|
$this->chosenFrame($image, $this->position)
|
||||||
|
]),
|
||||||
|
$image->exif()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -2,22 +2,16 @@
|
|||||||
|
|
||||||
namespace Intervention\Image\Drivers\Gd\Modifiers;
|
namespace Intervention\Image\Drivers\Gd\Modifiers;
|
||||||
|
|
||||||
|
use Intervention\Image\Drivers\DriverModifier;
|
||||||
use Intervention\Image\Interfaces\FrameInterface;
|
use Intervention\Image\Interfaces\FrameInterface;
|
||||||
use Intervention\Image\Interfaces\ImageInterface;
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
use Intervention\Image\Interfaces\ModifierInterface;
|
|
||||||
use Intervention\Image\Interfaces\SizeInterface;
|
use Intervention\Image\Interfaces\SizeInterface;
|
||||||
|
|
||||||
class ResizeModifier implements ModifierInterface
|
class ResizeModifier extends DriverModifier
|
||||||
{
|
{
|
||||||
public function __construct(protected ?int $width = null, protected ?int $height = null)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
public function apply(ImageInterface $image): ImageInterface
|
public function apply(ImageInterface $image): ImageInterface
|
||||||
{
|
{
|
||||||
$resizeTo = $this->getAdjustedSize($image);
|
$resizeTo = $this->getAdjustedSize($image);
|
||||||
|
|
||||||
foreach ($image as $frame) {
|
foreach ($image as $frame) {
|
||||||
$this->resizeFrame($frame, $resizeTo);
|
$this->resizeFrame($frame, $resizeTo);
|
||||||
}
|
}
|
||||||
@@ -25,12 +19,7 @@ class ResizeModifier implements ModifierInterface
|
|||||||
return $image;
|
return $image;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getAdjustedSize(ImageInterface $image): SizeInterface
|
private function resizeFrame(FrameInterface $frame, SizeInterface $resizeTo): void
|
||||||
{
|
|
||||||
return $image->size()->resize($this->width, $this->height);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function resizeFrame(FrameInterface $frame, SizeInterface $resizeTo): void
|
|
||||||
{
|
{
|
||||||
// create new image
|
// create new image
|
||||||
$modified = imagecreatetruecolor(
|
$modified = imagecreatetruecolor(
|
||||||
@@ -38,8 +27,8 @@ class ResizeModifier implements ModifierInterface
|
|||||||
$resizeTo->height()
|
$resizeTo->height()
|
||||||
);
|
);
|
||||||
|
|
||||||
// get current image
|
// get current GDImage
|
||||||
$current = $frame->core();
|
$current = $frame->data();
|
||||||
|
|
||||||
// preserve transparency
|
// preserve transparency
|
||||||
$transIndex = imagecolortransparent($current);
|
$transIndex = imagecolortransparent($current);
|
||||||
@@ -69,6 +58,11 @@ class ResizeModifier implements ModifierInterface
|
|||||||
);
|
);
|
||||||
|
|
||||||
// set new content as recource
|
// set new content as recource
|
||||||
$frame->setCore($modified);
|
$frame->setData($modified);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getAdjustedSize(ImageInterface $image): SizeInterface
|
||||||
|
{
|
||||||
|
return $image->size()->resize($this->width, $this->height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -2,23 +2,18 @@
|
|||||||
|
|
||||||
namespace Intervention\Image\Drivers\Gd\Modifiers;
|
namespace Intervention\Image\Drivers\Gd\Modifiers;
|
||||||
|
|
||||||
|
use Intervention\Image\Drivers\DriverModifier;
|
||||||
use Intervention\Image\Interfaces\ImageInterface;
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
use Intervention\Image\Interfaces\ModifierInterface;
|
|
||||||
|
|
||||||
class ResolutionModifier implements ModifierInterface
|
class ResolutionModifier extends DriverModifier
|
||||||
{
|
{
|
||||||
public function __construct(protected float $x, protected float $y)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
public function apply(ImageInterface $image): ImageInterface
|
public function apply(ImageInterface $image): ImageInterface
|
||||||
{
|
{
|
||||||
$x = intval(round($this->x));
|
$x = intval(round($this->x));
|
||||||
$y = intval(round($this->y));
|
$y = intval(round($this->y));
|
||||||
|
|
||||||
foreach ($image as $frame) {
|
foreach ($image as $frame) {
|
||||||
imageresolution($frame->core(), $x, $y);
|
imageresolution($frame->data(), $x, $y);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $image;
|
return $image;
|
||||||
|
@@ -5,29 +5,24 @@ namespace Intervention\Image\Drivers\Gd\Modifiers;
|
|||||||
use Intervention\Image\Colors\Rgb\Channels\Blue;
|
use Intervention\Image\Colors\Rgb\Channels\Blue;
|
||||||
use Intervention\Image\Colors\Rgb\Channels\Green;
|
use Intervention\Image\Colors\Rgb\Channels\Green;
|
||||||
use Intervention\Image\Colors\Rgb\Channels\Red;
|
use Intervention\Image\Colors\Rgb\Channels\Red;
|
||||||
use Intervention\Image\Drivers\Abstract\Modifiers\AbstractRotateModifier;
|
use Intervention\Image\Drivers\DriverModifier;
|
||||||
use Intervention\Image\Drivers\Gd\Traits\CanHandleColors;
|
|
||||||
use Intervention\Image\Exceptions\RuntimeException;
|
use Intervention\Image\Exceptions\RuntimeException;
|
||||||
use Intervention\Image\Exceptions\MissingDriverComponentException;
|
use Intervention\Image\Exceptions\MissingDriverComponentException;
|
||||||
use Intervention\Image\Geometry\Rectangle;
|
use Intervention\Image\Geometry\Rectangle;
|
||||||
use Intervention\Image\Interfaces\ColorInterface;
|
use Intervention\Image\Interfaces\ColorInterface;
|
||||||
use Intervention\Image\Interfaces\FrameInterface;
|
use Intervention\Image\Interfaces\FrameInterface;
|
||||||
use Intervention\Image\Interfaces\ImageInterface;
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
use Intervention\Image\Interfaces\ModifierInterface;
|
use Intervention\Image\Modifiers\FillModifier;
|
||||||
use Intervention\Image\Traits\CanBuildNewImage;
|
|
||||||
use ReflectionException;
|
use ReflectionException;
|
||||||
|
|
||||||
class RotateModifier extends AbstractRotateModifier implements ModifierInterface
|
class RotateModifier extends DriverModifier
|
||||||
{
|
{
|
||||||
use CanHandleColors;
|
|
||||||
use CanBuildNewImage;
|
|
||||||
|
|
||||||
public function apply(ImageInterface $image): ImageInterface
|
public function apply(ImageInterface $image): ImageInterface
|
||||||
{
|
{
|
||||||
$background = $this->handleInput($this->background);
|
$background = $this->driver()->handleInput($this->background);
|
||||||
|
|
||||||
foreach ($image as $frame) {
|
foreach ($image as $frame) {
|
||||||
$this->modify($frame, $background);
|
$this->modifyFrame($frame, $background);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $image;
|
return $image;
|
||||||
@@ -44,12 +39,12 @@ class RotateModifier extends AbstractRotateModifier implements ModifierInterface
|
|||||||
* @throws MissingDriverComponentException
|
* @throws MissingDriverComponentException
|
||||||
* @throws ReflectionException
|
* @throws ReflectionException
|
||||||
*/
|
*/
|
||||||
protected function modify(FrameInterface $frame, ColorInterface $background): void
|
protected function modifyFrame(FrameInterface $frame, ColorInterface $background): void
|
||||||
{
|
{
|
||||||
// get transparent color from frame core
|
// get transparent color from frame core
|
||||||
$transparent = match ($transparent = imagecolortransparent($frame->core())) {
|
$transparent = match ($transparent = imagecolortransparent($frame->data())) {
|
||||||
-1 => imagecolorallocatealpha(
|
-1 => imagecolorallocatealpha(
|
||||||
$frame->core(),
|
$frame->data(),
|
||||||
$background->channel(Red::class)->value(),
|
$background->channel(Red::class)->value(),
|
||||||
$background->channel(Green::class)->value(),
|
$background->channel(Green::class)->value(),
|
||||||
$background->channel(Blue::class)->value(),
|
$background->channel(Blue::class)->value(),
|
||||||
@@ -60,7 +55,7 @@ class RotateModifier extends AbstractRotateModifier implements ModifierInterface
|
|||||||
|
|
||||||
// rotate original image against transparent background
|
// rotate original image against transparent background
|
||||||
$rotated = imagerotate(
|
$rotated = imagerotate(
|
||||||
$frame->core(),
|
$frame->data(),
|
||||||
$this->rotationAngle(),
|
$this->rotationAngle(),
|
||||||
$transparent
|
$transparent
|
||||||
);
|
);
|
||||||
@@ -73,19 +68,20 @@ class RotateModifier extends AbstractRotateModifier implements ModifierInterface
|
|||||||
|
|
||||||
// create size from original and rotate points
|
// create size from original and rotate points
|
||||||
$cutout = (new Rectangle(
|
$cutout = (new Rectangle(
|
||||||
imagesx($frame->core()),
|
imagesx($frame->data()),
|
||||||
imagesy($frame->core()),
|
imagesy($frame->data()),
|
||||||
$container->pivot()
|
$container->pivot()
|
||||||
))->align('center')
|
))->align('center')
|
||||||
->valign('center')
|
->valign('center')
|
||||||
->rotate($this->rotationAngle() * -1);
|
->rotate($this->rotationAngle() * -1);
|
||||||
|
|
||||||
// create new gd core
|
// create new gd image
|
||||||
$modified = $this->imageFactory()->newCore(
|
$modified = $this->driver()->createImage(
|
||||||
imagesx($rotated),
|
imagesx($rotated),
|
||||||
imagesy($rotated),
|
imagesy($rotated)
|
||||||
$background
|
)->modify(new FillModifier($background))
|
||||||
);
|
->core()
|
||||||
|
->native();
|
||||||
|
|
||||||
// draw the cutout on new gd image to have a transparent
|
// draw the cutout on new gd image to have a transparent
|
||||||
// background where the rotated image will be placed
|
// background where the rotated image will be placed
|
||||||
@@ -109,6 +105,6 @@ class RotateModifier extends AbstractRotateModifier implements ModifierInterface
|
|||||||
imagesy($rotated)
|
imagesy($rotated)
|
||||||
);
|
);
|
||||||
|
|
||||||
$frame->setCore($modified);
|
$frame->setData($modified);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -2,27 +2,22 @@
|
|||||||
|
|
||||||
namespace Intervention\Image\Drivers\Gd\Modifiers;
|
namespace Intervention\Image\Drivers\Gd\Modifiers;
|
||||||
|
|
||||||
|
use Intervention\Image\Drivers\DriverModifier;
|
||||||
use Intervention\Image\Interfaces\ImageInterface;
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
use Intervention\Image\Interfaces\ModifierInterface;
|
|
||||||
|
|
||||||
class SharpenModifier implements ModifierInterface
|
class SharpenModifier extends DriverModifier
|
||||||
{
|
{
|
||||||
public function __construct(protected int $amount)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
public function apply(ImageInterface $image): ImageInterface
|
public function apply(ImageInterface $image): ImageInterface
|
||||||
{
|
{
|
||||||
$matrix = $this->matrix();
|
$matrix = $this->matrix();
|
||||||
foreach ($image as $frame) {
|
foreach ($image as $frame) {
|
||||||
imageconvolution($frame->core(), $matrix, 1, 0);
|
imageconvolution($frame->data(), $matrix, 1, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $image;
|
return $image;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function matrix(): array
|
private function matrix(): array
|
||||||
{
|
{
|
||||||
$min = $this->amount >= 10 ? $this->amount * -0.01 : 0;
|
$min = $this->amount >= 10 ? $this->amount * -0.01 : 0;
|
||||||
$max = $this->amount * -0.025;
|
$max = $this->amount * -0.025;
|
||||||
|
@@ -2,26 +2,25 @@
|
|||||||
|
|
||||||
namespace Intervention\Image\Drivers\Gd\Modifiers;
|
namespace Intervention\Image\Drivers\Gd\Modifiers;
|
||||||
|
|
||||||
use Intervention\Image\Drivers\Abstract\AbstractTextWriter;
|
use Intervention\Image\Drivers\DriverModifier;
|
||||||
use Intervention\Image\Drivers\Gd\Font;
|
|
||||||
use Intervention\Image\Drivers\Gd\Traits\CanHandleColors;
|
use Intervention\Image\Drivers\Gd\Traits\CanHandleColors;
|
||||||
use Intervention\Image\Interfaces\ImageInterface;
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
|
|
||||||
class TextWriter extends AbstractTextWriter
|
class TextWriter extends DriverModifier
|
||||||
{
|
{
|
||||||
use CanHandleColors;
|
use CanHandleColors;
|
||||||
|
|
||||||
public function apply(ImageInterface $image): ImageInterface
|
public function apply(ImageInterface $image): ImageInterface
|
||||||
{
|
{
|
||||||
$lines = $this->getAlignedTextBlock();
|
$lines = $this->getAlignedTextBlock();
|
||||||
$font = $this->failIfNotClass($this->getFont(), Font::class);
|
$font = $this->font;
|
||||||
$color = $this->colorToInteger($font->getColor());
|
$color = $this->colorToInteger($font->getColor());
|
||||||
|
|
||||||
foreach ($image as $frame) {
|
foreach ($image as $frame) {
|
||||||
if ($this->font->hasFilename()) {
|
if ($this->font->hasFilename()) {
|
||||||
foreach ($lines as $line) {
|
foreach ($lines as $line) {
|
||||||
imagettftext(
|
imagettftext(
|
||||||
$frame->core(),
|
$frame->data(),
|
||||||
$font->getSize(),
|
$font->getSize(),
|
||||||
$font->getAngle() * (-1),
|
$font->getAngle() * (-1),
|
||||||
$line->getPosition()->x(),
|
$line->getPosition()->x(),
|
||||||
@@ -34,7 +33,7 @@ class TextWriter extends AbstractTextWriter
|
|||||||
} else {
|
} else {
|
||||||
foreach ($lines as $line) {
|
foreach ($lines as $line) {
|
||||||
imagestring(
|
imagestring(
|
||||||
$frame->core(),
|
$frame->data(),
|
||||||
$font->getGdFont(),
|
$font->getGdFont(),
|
||||||
$line->getPosition()->x(),
|
$line->getPosition()->x(),
|
||||||
$line->getPosition()->y(),
|
$line->getPosition()->y(),
|
||||||
|
@@ -10,7 +10,7 @@ use Intervention\Image\Colors\Rgb\Channels\Blue;
|
|||||||
use Intervention\Image\Colors\Rgb\Channels\Green;
|
use Intervention\Image\Colors\Rgb\Channels\Green;
|
||||||
use Intervention\Image\Colors\Rgb\Channels\Red;
|
use Intervention\Image\Colors\Rgb\Channels\Red;
|
||||||
|
|
||||||
trait CanHandleColors
|
trait DELETE___CanHandleColors
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Allocate given color in given gd image and return color value/index
|
* Allocate given color in given gd image and return color value/index
|
||||||
|
22
src/Drivers/Imagick/ColorProcessor.php
Normal file
22
src/Drivers/Imagick/ColorProcessor.php
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Intervention\Image\Drivers\Imagick;
|
||||||
|
|
||||||
|
use ImagickPixel;
|
||||||
|
use Intervention\Image\Interfaces\ColorInterface;
|
||||||
|
use Intervention\Image\Interfaces\ColorProcessorInterface;
|
||||||
|
use Intervention\Image\Interfaces\ColorspaceInterface;
|
||||||
|
|
||||||
|
class ColorProcessor implements ColorProcessorInterface
|
||||||
|
{
|
||||||
|
public function __construct(protected ColorspaceInterface $colorspace)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function colorToNative(ColorInterface $color): ImagickPixel
|
||||||
|
{
|
||||||
|
return new ImagickPixel(
|
||||||
|
(string) $color->convertTo($this->colorspace)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
107
src/Drivers/Imagick/Core.php
Normal file
107
src/Drivers/Imagick/Core.php
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Intervention\Image\Drivers\Imagick;
|
||||||
|
|
||||||
|
use Imagick;
|
||||||
|
use ImagickException;
|
||||||
|
use Iterator;
|
||||||
|
use Intervention\Image\Interfaces\ColorspaceInterface;
|
||||||
|
use Intervention\Image\Interfaces\CoreInterface;
|
||||||
|
use Intervention\Image\Colors\Cmyk\Colorspace as CmykColorspace;
|
||||||
|
use Intervention\Image\Colors\Rgb\Colorspace as RgbColorspace;
|
||||||
|
use Intervention\Image\Exceptions\AnimationException;
|
||||||
|
use Intervention\Image\Interfaces\FrameInterface;
|
||||||
|
|
||||||
|
class Core implements CoreInterface, Iterator
|
||||||
|
{
|
||||||
|
protected int $iteratorIndex = 0;
|
||||||
|
|
||||||
|
public function __construct(protected Imagick $imagick)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function count(): int
|
||||||
|
{
|
||||||
|
return $this->imagick->getNumberImages();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function current(): mixed
|
||||||
|
{
|
||||||
|
$this->imagick->setIteratorIndex($this->iteratorIndex);
|
||||||
|
|
||||||
|
return new Frame($this->imagick->current());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function next(): void
|
||||||
|
{
|
||||||
|
$this->iteratorIndex = $this->iteratorIndex + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function key(): mixed
|
||||||
|
{
|
||||||
|
return $this->iteratorIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function valid(): bool
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$result = $this->imagick->setIteratorIndex($this->iteratorIndex);
|
||||||
|
} catch (ImagickException $e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function rewind(): void
|
||||||
|
{
|
||||||
|
$this->iteratorIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function native()
|
||||||
|
{
|
||||||
|
return $this->imagick;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function width(): int
|
||||||
|
{
|
||||||
|
return $this->imagick->getImageWidth();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function height(): int
|
||||||
|
{
|
||||||
|
return $this->imagick->getImageHeight();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function frame(int $position): FrameInterface
|
||||||
|
{
|
||||||
|
foreach ($this->imagick as $core) {
|
||||||
|
if ($core->getIteratorIndex() == $position) {
|
||||||
|
return new Frame($core);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new AnimationException('Frame #' . $position . ' is not be found in the image.');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function loops(): int
|
||||||
|
{
|
||||||
|
return $this->imagick->getImageIterations();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setLoops(int $loops): CoreInterface
|
||||||
|
{
|
||||||
|
$this->imagick = $this->imagick->coalesceImages();
|
||||||
|
$this->imagick->setImageIterations($loops);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function colorspace(): ColorspaceInterface
|
||||||
|
{
|
||||||
|
return match ($this->imagick->getImageColorspace()) {
|
||||||
|
Imagick::COLORSPACE_CMYK => new CmykColorspace(),
|
||||||
|
default => new RgbColorspace(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
@@ -4,9 +4,11 @@ namespace Intervention\Image\Drivers\Imagick\Decoders;
|
|||||||
|
|
||||||
use Imagick;
|
use Imagick;
|
||||||
use ImagickException;
|
use ImagickException;
|
||||||
use Intervention\Image\Drivers\Abstract\Decoders\AbstractDecoder;
|
use Intervention\Image\Drivers\AbstractDecoder;
|
||||||
use Intervention\Image\Drivers\Imagick\Image;
|
use Intervention\Image\Drivers\Imagick\Core;
|
||||||
|
use Intervention\Image\Drivers\Imagick\Driver;
|
||||||
use Intervention\Image\Exceptions\DecoderException;
|
use Intervention\Image\Exceptions\DecoderException;
|
||||||
|
use Intervention\Image\Image;
|
||||||
use Intervention\Image\Interfaces\ColorInterface;
|
use Intervention\Image\Interfaces\ColorInterface;
|
||||||
use Intervention\Image\Interfaces\DecoderInterface;
|
use Intervention\Image\Interfaces\DecoderInterface;
|
||||||
use Intervention\Image\Interfaces\ImageInterface;
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
@@ -46,9 +48,11 @@ class BinaryImageDecoder extends AbstractDecoder implements DecoderInterface
|
|||||||
// set new orientation in image
|
// set new orientation in image
|
||||||
$imagick->setImageOrientation(Imagick::ORIENTATION_TOPLEFT);
|
$imagick->setImageOrientation(Imagick::ORIENTATION_TOPLEFT);
|
||||||
|
|
||||||
$image = new Image($imagick);
|
$image = new Image(
|
||||||
$image->setLoops($imagick->getImageIterations());
|
new Driver(),
|
||||||
$image->setExif($this->decodeExifData($input));
|
new Core($imagick),
|
||||||
|
$this->decodeExifData($input)
|
||||||
|
);
|
||||||
|
|
||||||
return $image;
|
return $image;
|
||||||
}
|
}
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
namespace Intervention\Image\Drivers\Imagick\Decoders;
|
namespace Intervention\Image\Drivers\Imagick\Decoders;
|
||||||
|
|
||||||
use Intervention\Image\Drivers\Abstract\Decoders\AbstractDecoder;
|
use Intervention\Image\Drivers\AbstractDecoder;
|
||||||
use Intervention\Image\Exceptions\DecoderException;
|
use Intervention\Image\Exceptions\DecoderException;
|
||||||
use Intervention\Image\Interfaces\ColorInterface;
|
use Intervention\Image\Interfaces\ColorInterface;
|
||||||
use Intervention\Image\Interfaces\DecoderInterface;
|
use Intervention\Image\Interfaces\DecoderInterface;
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
namespace Intervention\Image\Drivers\Imagick\Decoders;
|
namespace Intervention\Image\Drivers\Imagick\Decoders;
|
||||||
|
|
||||||
use Intervention\Image\Drivers\Abstract\Decoders\AbstractDecoder;
|
use Intervention\Image\Drivers\AbstractDecoder;
|
||||||
use Intervention\Image\Exceptions\DecoderException;
|
use Intervention\Image\Exceptions\DecoderException;
|
||||||
use Intervention\Image\Interfaces\ColorInterface;
|
use Intervention\Image\Interfaces\ColorInterface;
|
||||||
use Intervention\Image\Interfaces\DecoderInterface;
|
use Intervention\Image\Interfaces\DecoderInterface;
|
||||||
|
38
src/Drivers/Imagick/Driver.php
Normal file
38
src/Drivers/Imagick/Driver.php
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Intervention\Image\Drivers\Imagick;
|
||||||
|
|
||||||
|
use Imagick;
|
||||||
|
use ImagickPixel;
|
||||||
|
use Intervention\Image\Drivers\AbstractDriver;
|
||||||
|
use Intervention\Image\Image;
|
||||||
|
use Intervention\Image\Interfaces\ColorInterface;
|
||||||
|
use Intervention\Image\Interfaces\ColorspaceInterface;
|
||||||
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
|
|
||||||
|
class Driver extends AbstractDriver
|
||||||
|
{
|
||||||
|
public function createImage(int $width, int $height): ImageInterface
|
||||||
|
{
|
||||||
|
$background = new ImagickPixel('rgba(0, 0, 0, 0)');
|
||||||
|
|
||||||
|
$imagick = new Imagick();
|
||||||
|
$imagick->newImage($width, $height, $background, 'png');
|
||||||
|
$imagick->setType(Imagick::IMGTYPE_UNDEFINED);
|
||||||
|
$imagick->setImageType(Imagick::IMGTYPE_UNDEFINED);
|
||||||
|
$imagick->setColorspace(Imagick::COLORSPACE_SRGB);
|
||||||
|
$imagick->setImageResolution(96, 96);
|
||||||
|
|
||||||
|
return new Image($this, new Core($imagick));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handleInput(mixed $input): ImageInterface|ColorInterface
|
||||||
|
{
|
||||||
|
return (new InputHandler())->handle($input);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function colorToNative(ColorInterface $color, ColorspaceInterface $colorspace): mixed
|
||||||
|
{
|
||||||
|
return (new ColorProcessor($colorspace))->colorToNative($color);
|
||||||
|
}
|
||||||
|
}
|
@@ -3,24 +3,18 @@
|
|||||||
namespace Intervention\Image\Drivers\Imagick\Encoders;
|
namespace Intervention\Image\Drivers\Imagick\Encoders;
|
||||||
|
|
||||||
use Imagick;
|
use Imagick;
|
||||||
use Intervention\Image\Drivers\Abstract\Encoders\AbstractEncoder;
|
use Intervention\Image\Drivers\DriverEncoder;
|
||||||
use Intervention\Image\EncodedImage;
|
use Intervention\Image\EncodedImage;
|
||||||
use Intervention\Image\Interfaces\EncoderInterface;
|
|
||||||
use Intervention\Image\Interfaces\ImageInterface;
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
|
|
||||||
class AvifEncoder extends AbstractEncoder implements EncoderInterface
|
class AvifEncoder extends DriverEncoder
|
||||||
{
|
{
|
||||||
public function __construct(int $quality)
|
|
||||||
{
|
|
||||||
$this->quality = $quality;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function encode(ImageInterface $image): EncodedImage
|
public function encode(ImageInterface $image): EncodedImage
|
||||||
{
|
{
|
||||||
$format = 'AVIF';
|
$format = 'AVIF';
|
||||||
$compression = Imagick::COMPRESSION_ZIP;
|
$compression = Imagick::COMPRESSION_ZIP;
|
||||||
|
|
||||||
$imagick = $image->frame()->core();
|
$imagick = $image->core()->native();
|
||||||
$imagick->setFormat($format);
|
$imagick->setFormat($format);
|
||||||
$imagick->setImageFormat($format);
|
$imagick->setImageFormat($format);
|
||||||
$imagick->setCompression($compression);
|
$imagick->setCompression($compression);
|
||||||
|
@@ -3,26 +3,20 @@
|
|||||||
namespace Intervention\Image\Drivers\Imagick\Encoders;
|
namespace Intervention\Image\Drivers\Imagick\Encoders;
|
||||||
|
|
||||||
use Imagick;
|
use Imagick;
|
||||||
use Intervention\Image\Drivers\Abstract\Encoders\AbstractEncoder;
|
use Intervention\Image\Drivers\DriverEncoder;
|
||||||
use Intervention\Image\Drivers\Imagick\Modifiers\LimitColorsModifier;
|
use Intervention\Image\Modifiers\LimitColorsModifier;
|
||||||
use Intervention\Image\EncodedImage;
|
use Intervention\Image\EncodedImage;
|
||||||
use Intervention\Image\Interfaces\EncoderInterface;
|
|
||||||
use Intervention\Image\Interfaces\ImageInterface;
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
|
|
||||||
class BmpEncoder extends AbstractEncoder implements EncoderInterface
|
class BmpEncoder extends DriverEncoder
|
||||||
{
|
{
|
||||||
public function __construct(protected int $color_limit = 0)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
public function encode(ImageInterface $image): EncodedImage
|
public function encode(ImageInterface $image): EncodedImage
|
||||||
{
|
{
|
||||||
$format = 'bmp';
|
$format = 'bmp';
|
||||||
$compression = Imagick::COMPRESSION_NO;
|
$compression = Imagick::COMPRESSION_NO;
|
||||||
|
|
||||||
$image = $image->modify(new LimitColorsModifier($this->color_limit));
|
$image = $image->modify(new LimitColorsModifier($this->color_limit));
|
||||||
$imagick = $image->frame()->core();
|
$imagick = $image->core()->native();
|
||||||
$imagick->setFormat($format);
|
$imagick->setFormat($format);
|
||||||
$imagick->setImageFormat($format);
|
$imagick->setImageFormat($format);
|
||||||
$imagick->setCompression($compression);
|
$imagick->setCompression($compression);
|
||||||
|
@@ -3,37 +3,23 @@
|
|||||||
namespace Intervention\Image\Drivers\Imagick\Encoders;
|
namespace Intervention\Image\Drivers\Imagick\Encoders;
|
||||||
|
|
||||||
use Imagick;
|
use Imagick;
|
||||||
use Intervention\Image\Drivers\Abstract\Encoders\AbstractEncoder;
|
use Intervention\Image\Drivers\DriverEncoder;
|
||||||
use Intervention\Image\Drivers\Imagick\Image;
|
use Intervention\Image\Modifiers\LimitColorsModifier;
|
||||||
use Intervention\Image\Drivers\Imagick\Modifiers\LimitColorsModifier;
|
|
||||||
use Intervention\Image\EncodedImage;
|
use Intervention\Image\EncodedImage;
|
||||||
use Intervention\Image\Exceptions\EncoderException;
|
|
||||||
use Intervention\Image\Interfaces\EncoderInterface;
|
|
||||||
use Intervention\Image\Interfaces\ImageInterface;
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
use Intervention\Image\Traits\CanCheckType;
|
|
||||||
|
|
||||||
class GifEncoder extends AbstractEncoder implements EncoderInterface
|
class GifEncoder extends DriverEncoder
|
||||||
{
|
{
|
||||||
use CanCheckType;
|
|
||||||
|
|
||||||
public function __construct(protected int $color_limit = 0)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
public function encode(ImageInterface $image): EncodedImage
|
public function encode(ImageInterface $image): EncodedImage
|
||||||
{
|
{
|
||||||
|
$image = $image->modify(new LimitColorsModifier($this->color_limit));
|
||||||
|
|
||||||
|
|
||||||
$format = 'gif';
|
$format = 'gif';
|
||||||
$compression = Imagick::COMPRESSION_LZW;
|
$compression = Imagick::COMPRESSION_LZW;
|
||||||
|
|
||||||
if (!is_a($image, Image::class)) {
|
$imagick = $image->core()->native();
|
||||||
throw new EncoderException('Image does not match the current driver.');
|
|
||||||
}
|
|
||||||
|
|
||||||
$image = $this->failIfNotClass($image, Image::class);
|
|
||||||
|
|
||||||
$image = $image->modify(new LimitColorsModifier($this->color_limit));
|
|
||||||
$imagick = $image->getImagick();
|
|
||||||
$imagick->setFormat($format);
|
$imagick->setFormat($format);
|
||||||
$imagick->setImageFormat($format);
|
$imagick->setImageFormat($format);
|
||||||
$imagick->setCompression($compression);
|
$imagick->setCompression($compression);
|
||||||
|
@@ -3,24 +3,18 @@
|
|||||||
namespace Intervention\Image\Drivers\Imagick\Encoders;
|
namespace Intervention\Image\Drivers\Imagick\Encoders;
|
||||||
|
|
||||||
use Imagick;
|
use Imagick;
|
||||||
use Intervention\Image\Drivers\Abstract\Encoders\AbstractEncoder;
|
use Intervention\Image\Drivers\DriverEncoder;
|
||||||
use Intervention\Image\EncodedImage;
|
use Intervention\Image\EncodedImage;
|
||||||
use Intervention\Image\Interfaces\EncoderInterface;
|
|
||||||
use Intervention\Image\Interfaces\ImageInterface;
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
|
|
||||||
class JpegEncoder extends AbstractEncoder implements EncoderInterface
|
class JpegEncoder extends DriverEncoder
|
||||||
{
|
{
|
||||||
public function __construct(int $quality)
|
|
||||||
{
|
|
||||||
$this->quality = $quality;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function encode(ImageInterface $image): EncodedImage
|
public function encode(ImageInterface $image): EncodedImage
|
||||||
{
|
{
|
||||||
$format = 'jpeg';
|
$format = 'jpeg';
|
||||||
$compression = Imagick::COMPRESSION_JPEG;
|
$compression = Imagick::COMPRESSION_JPEG;
|
||||||
|
|
||||||
$imagick = $image->frame()->core();
|
$imagick = $image->core()->native();
|
||||||
$imagick->setImageBackgroundColor('white');
|
$imagick->setImageBackgroundColor('white');
|
||||||
$imagick->setBackgroundColor('white');
|
$imagick->setBackgroundColor('white');
|
||||||
$imagick->setFormat($format);
|
$imagick->setFormat($format);
|
||||||
|
@@ -3,26 +3,20 @@
|
|||||||
namespace Intervention\Image\Drivers\Imagick\Encoders;
|
namespace Intervention\Image\Drivers\Imagick\Encoders;
|
||||||
|
|
||||||
use Imagick;
|
use Imagick;
|
||||||
use Intervention\Image\Drivers\Abstract\Encoders\AbstractEncoder;
|
use Intervention\Image\Drivers\DriverEncoder;
|
||||||
use Intervention\Image\Drivers\Imagick\Modifiers\LimitColorsModifier;
|
use Intervention\Image\Modifiers\LimitColorsModifier;
|
||||||
use Intervention\Image\EncodedImage;
|
use Intervention\Image\EncodedImage;
|
||||||
use Intervention\Image\Interfaces\EncoderInterface;
|
|
||||||
use Intervention\Image\Interfaces\ImageInterface;
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
|
|
||||||
class PngEncoder extends AbstractEncoder implements EncoderInterface
|
class PngEncoder extends DriverEncoder
|
||||||
{
|
{
|
||||||
public function __construct(protected int $color_limit = 0)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
public function encode(ImageInterface $image): EncodedImage
|
public function encode(ImageInterface $image): EncodedImage
|
||||||
{
|
{
|
||||||
$format = 'png';
|
$format = 'png';
|
||||||
$compression = Imagick::COMPRESSION_ZIP;
|
$compression = Imagick::COMPRESSION_ZIP;
|
||||||
|
|
||||||
$image = $image->modify(new LimitColorsModifier($this->color_limit));
|
$image = $image->modify(new LimitColorsModifier($this->color_limit));
|
||||||
$imagick = $image->frame()->core();
|
$imagick = $image->core()->frame()->data();
|
||||||
$imagick->setFormat($format);
|
$imagick->setFormat($format);
|
||||||
$imagick->setImageFormat($format);
|
$imagick->setImageFormat($format);
|
||||||
$imagick->setCompression($compression);
|
$imagick->setCompression($compression);
|
||||||
|
@@ -4,24 +4,18 @@ namespace Intervention\Image\Drivers\Imagick\Encoders;
|
|||||||
|
|
||||||
use Imagick;
|
use Imagick;
|
||||||
use ImagickPixel;
|
use ImagickPixel;
|
||||||
use Intervention\Image\Drivers\Abstract\Encoders\AbstractEncoder;
|
use Intervention\Image\Drivers\DriverEncoder;
|
||||||
use Intervention\Image\EncodedImage;
|
use Intervention\Image\EncodedImage;
|
||||||
use Intervention\Image\Interfaces\EncoderInterface;
|
|
||||||
use Intervention\Image\Interfaces\ImageInterface;
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
|
|
||||||
class WebpEncoder extends AbstractEncoder implements EncoderInterface
|
class WebpEncoder extends DriverEncoder
|
||||||
{
|
{
|
||||||
public function __construct(int $quality)
|
|
||||||
{
|
|
||||||
$this->quality = $quality;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function encode(ImageInterface $image): EncodedImage
|
public function encode(ImageInterface $image): EncodedImage
|
||||||
{
|
{
|
||||||
$format = 'webp';
|
$format = 'webp';
|
||||||
$compression = Imagick::COMPRESSION_ZIP;
|
$compression = Imagick::COMPRESSION_ZIP;
|
||||||
|
|
||||||
$imagick = $image->frame()->core();
|
$imagick = $image->core()->native();
|
||||||
$imagick->setImageBackgroundColor(new ImagickPixel('transparent'));
|
$imagick->setImageBackgroundColor(new ImagickPixel('transparent'));
|
||||||
|
|
||||||
$imagick = $imagick->mergeImageLayers(Imagick::LAYERMETHOD_MERGE);
|
$imagick = $imagick->mergeImageLayers(Imagick::LAYERMETHOD_MERGE);
|
||||||
|
@@ -13,7 +13,7 @@ use Intervention\Image\Interfaces\ImageInterface;
|
|||||||
use Intervention\Image\Traits\CanCheckType;
|
use Intervention\Image\Traits\CanCheckType;
|
||||||
use Intervention\Image\Traits\CanHandleInput;
|
use Intervention\Image\Traits\CanHandleInput;
|
||||||
|
|
||||||
class Factory implements FactoryInterface
|
class DELETE___FactoryFactory implements FactoryInterface
|
||||||
{
|
{
|
||||||
use CanHandleInput;
|
use CanHandleInput;
|
||||||
use CanCheckType;
|
use CanCheckType;
|
||||||
|
@@ -4,7 +4,7 @@ namespace Intervention\Image\Drivers\Imagick;
|
|||||||
|
|
||||||
use Imagick;
|
use Imagick;
|
||||||
use ImagickDraw;
|
use ImagickDraw;
|
||||||
use Intervention\Image\Drivers\Abstract\AbstractFont;
|
use Intervention\Image\Drivers\AbstractFont;
|
||||||
use Intervention\Image\Drivers\Imagick\Traits\CanHandleColors;
|
use Intervention\Image\Drivers\Imagick\Traits\CanHandleColors;
|
||||||
use Intervention\Image\Exceptions\FontException;
|
use Intervention\Image\Exceptions\FontException;
|
||||||
use Intervention\Image\Geometry\Polygon;
|
use Intervention\Image\Geometry\Polygon;
|
||||||
|
@@ -4,66 +4,72 @@ namespace Intervention\Image\Drivers\Imagick;
|
|||||||
|
|
||||||
use Imagick;
|
use Imagick;
|
||||||
use Intervention\Image\Geometry\Rectangle;
|
use Intervention\Image\Geometry\Rectangle;
|
||||||
|
use Intervention\Image\Image;
|
||||||
|
use Intervention\Image\Interfaces\DriverInterface;
|
||||||
use Intervention\Image\Interfaces\FrameInterface;
|
use Intervention\Image\Interfaces\FrameInterface;
|
||||||
use Intervention\Image\Interfaces\ImageInterface;
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
use Intervention\Image\Interfaces\SizeInterface;
|
use Intervention\Image\Interfaces\SizeInterface;
|
||||||
|
|
||||||
class Frame implements FrameInterface
|
class Frame implements FrameInterface
|
||||||
{
|
{
|
||||||
public function __construct(protected Imagick $core)
|
public function __construct(protected Imagick $data)
|
||||||
{
|
{
|
||||||
//
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setCore($core): FrameInterface
|
public function toImage(DriverInterface $driver): ImageInterface
|
||||||
{
|
{
|
||||||
$this->core = $core;
|
return new Image($driver, new Core($this->data()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setData($data): FrameInterface
|
||||||
|
{
|
||||||
|
$this->data = $data;
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function core(): Imagick
|
public function data(): Imagick
|
||||||
{
|
{
|
||||||
return $this->core;
|
return $this->data;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function size(): SizeInterface
|
public function size(): SizeInterface
|
||||||
{
|
{
|
||||||
return new Rectangle(
|
return new Rectangle(
|
||||||
$this->core->getImageWidth(),
|
$this->data->getImageWidth(),
|
||||||
$this->core->getImageHeight()
|
$this->data->getImageHeight()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function delay(): float
|
public function delay(): float
|
||||||
{
|
{
|
||||||
return $this->core->getImageDelay() / 100;
|
return $this->data->getImageDelay() / 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setDelay(float $delay): FrameInterface
|
public function setDelay(float $delay): FrameInterface
|
||||||
{
|
{
|
||||||
$this->core->setImageDelay(intval(round($delay * 100)));
|
$this->data->setImageDelay(intval(round($delay * 100)));
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function dispose(): int
|
public function dispose(): int
|
||||||
{
|
{
|
||||||
return $this->core->getImageDispose();
|
return $this->data->getImageDispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setDispose(int $dispose): FrameInterface
|
public function setDispose(int $dispose): FrameInterface
|
||||||
{
|
{
|
||||||
$this->core->setImageDispose($dispose);
|
$this->data->setImageDispose($dispose);
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setOffset(int $left, int $top): FrameInterface
|
public function setOffset(int $left, int $top): FrameInterface
|
||||||
{
|
{
|
||||||
$this->core->setImagePage(
|
$this->data->setImagePage(
|
||||||
$this->core->getImageWidth(),
|
$this->data->getImageWidth(),
|
||||||
$this->core->getImageHeight(),
|
$this->data->getImageHeight(),
|
||||||
$left,
|
$left,
|
||||||
$top
|
$top
|
||||||
);
|
);
|
||||||
@@ -73,7 +79,7 @@ class Frame implements FrameInterface
|
|||||||
|
|
||||||
public function offsetLeft(): int
|
public function offsetLeft(): int
|
||||||
{
|
{
|
||||||
return $this->core->getImagePage()['x'];
|
return $this->data->getImagePage()['x'];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setOffsetLeft(int $offset): FrameInterface
|
public function setOffsetLeft(int $offset): FrameInterface
|
||||||
@@ -83,16 +89,11 @@ class Frame implements FrameInterface
|
|||||||
|
|
||||||
public function offsetTop(): int
|
public function offsetTop(): int
|
||||||
{
|
{
|
||||||
return $this->core->getImagePage()['y'];
|
return $this->data->getImagePage()['y'];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setOffsetTop(int $offset): FrameInterface
|
public function setOffsetTop(int $offset): FrameInterface
|
||||||
{
|
{
|
||||||
return $this->setOffset($this->offsetLeft(), $offset);
|
return $this->setOffset($this->offsetLeft(), $offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function toImage(): ImageInterface
|
|
||||||
{
|
|
||||||
return new Image($this->core());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -23,7 +23,7 @@ use Intervention\Image\Interfaces\ResolutionInterface;
|
|||||||
use Intervention\Image\Resolution;
|
use Intervention\Image\Resolution;
|
||||||
use Iterator;
|
use Iterator;
|
||||||
|
|
||||||
class Image extends AbstractImage implements ImageInterface, Iterator
|
class DELETE__Image extends AbstractImage implements ImageInterface, Iterator
|
||||||
{
|
{
|
||||||
use CanHandleColors;
|
use CanHandleColors;
|
||||||
|
|
||||||
|
@@ -7,7 +7,7 @@ use Intervention\Image\Colors\Rgb\Decoders\StringColorDecoder as RgbStringColorD
|
|||||||
use Intervention\Image\Colors\Rgb\Decoders\HtmlColornameDecoder;
|
use Intervention\Image\Colors\Rgb\Decoders\HtmlColornameDecoder;
|
||||||
use Intervention\Image\Colors\Rgb\Decoders\TransparentColorDecoder;
|
use Intervention\Image\Colors\Rgb\Decoders\TransparentColorDecoder;
|
||||||
use Intervention\Image\Colors\Cmyk\Decoders\StringColorDecoder as CmykStringColorDecoder;
|
use Intervention\Image\Colors\Cmyk\Decoders\StringColorDecoder as CmykStringColorDecoder;
|
||||||
use Intervention\Image\Drivers\Abstract\AbstractInputHandler;
|
use Intervention\Image\Drivers\AbstractInputHandler;
|
||||||
use Intervention\Image\Drivers\Imagick\Decoders\ImageObjectDecoder;
|
use Intervention\Image\Drivers\Imagick\Decoders\ImageObjectDecoder;
|
||||||
use Intervention\Image\Drivers\Imagick\Decoders\ColorObjectDecoder;
|
use Intervention\Image\Drivers\Imagick\Decoders\ColorObjectDecoder;
|
||||||
use Intervention\Image\Drivers\Imagick\Decoders\FilePointerImageDecoder;
|
use Intervention\Image\Drivers\Imagick\Decoders\FilePointerImageDecoder;
|
||||||
|
@@ -2,20 +2,15 @@
|
|||||||
|
|
||||||
namespace Intervention\Image\Drivers\Imagick\Modifiers;
|
namespace Intervention\Image\Drivers\Imagick\Modifiers;
|
||||||
|
|
||||||
|
use Intervention\Image\Drivers\DriverModifier;
|
||||||
use Intervention\Image\Interfaces\ImageInterface;
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
use Intervention\Image\Interfaces\ModifierInterface;
|
|
||||||
|
|
||||||
class BlurModifier implements ModifierInterface
|
class BlurModifier extends DriverModifier
|
||||||
{
|
{
|
||||||
public function __construct(protected int $amount)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
public function apply(ImageInterface $image): ImageInterface
|
public function apply(ImageInterface $image): ImageInterface
|
||||||
{
|
{
|
||||||
foreach ($image as $frame) {
|
foreach ($image as $frame) {
|
||||||
$frame->core()->blurImage(1 * $this->amount, 0.5 * $this->amount);
|
$frame->data()->blurImage(1 * $this->amount, 0.5 * $this->amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $image;
|
return $image;
|
||||||
|
@@ -2,20 +2,15 @@
|
|||||||
|
|
||||||
namespace Intervention\Image\Drivers\Imagick\Modifiers;
|
namespace Intervention\Image\Drivers\Imagick\Modifiers;
|
||||||
|
|
||||||
|
use Intervention\Image\Drivers\DriverModifier;
|
||||||
use Intervention\Image\Interfaces\ImageInterface;
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
use Intervention\Image\Interfaces\ModifierInterface;
|
|
||||||
|
|
||||||
class BrightnessModifier implements ModifierInterface
|
class BrightnessModifier extends DriverModifier
|
||||||
{
|
{
|
||||||
public function __construct(protected int $level)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
public function apply(ImageInterface $image): ImageInterface
|
public function apply(ImageInterface $image): ImageInterface
|
||||||
{
|
{
|
||||||
foreach ($image as $frame) {
|
foreach ($image as $frame) {
|
||||||
$frame->core()->modulateImage(100 + $this->level, 100, 100);
|
$frame->data()->modulateImage(100 + $this->level, 100, 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $image;
|
return $image;
|
||||||
|
@@ -3,31 +3,22 @@
|
|||||||
namespace Intervention\Image\Drivers\Imagick\Modifiers;
|
namespace Intervention\Image\Drivers\Imagick\Modifiers;
|
||||||
|
|
||||||
use Imagick;
|
use Imagick;
|
||||||
|
use Intervention\Image\Drivers\DriverModifier;
|
||||||
use Intervention\Image\Interfaces\ImageInterface;
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
use Intervention\Image\Interfaces\ModifierInterface;
|
|
||||||
|
|
||||||
class ColorizeModifier implements ModifierInterface
|
class ColorizeModifier extends DriverModifier
|
||||||
{
|
{
|
||||||
public function __construct(
|
|
||||||
protected int $red = 0,
|
|
||||||
protected int $green = 0,
|
|
||||||
protected int $blue = 0
|
|
||||||
) {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
public function apply(ImageInterface $image): ImageInterface
|
public function apply(ImageInterface $image): ImageInterface
|
||||||
{
|
{
|
||||||
// normalize colorize levels
|
|
||||||
$red = $this->normalizeLevel($this->red);
|
$red = $this->normalizeLevel($this->red);
|
||||||
$green = $this->normalizeLevel($this->green);
|
$green = $this->normalizeLevel($this->green);
|
||||||
$blue = $this->normalizeLevel($this->blue);
|
$blue = $this->normalizeLevel($this->blue);
|
||||||
|
|
||||||
foreach ($image as $frame) {
|
foreach ($image as $frame) {
|
||||||
$qrange = $frame->core()->getQuantumRange();
|
$qrange = $frame->data()->getQuantumRange();
|
||||||
$frame->core()->levelImage(0, $red, $qrange['quantumRangeLong'], Imagick::CHANNEL_RED);
|
$frame->data()->levelImage(0, $red, $qrange['quantumRangeLong'], Imagick::CHANNEL_RED);
|
||||||
$frame->core()->levelImage(0, $green, $qrange['quantumRangeLong'], Imagick::CHANNEL_GREEN);
|
$frame->data()->levelImage(0, $green, $qrange['quantumRangeLong'], Imagick::CHANNEL_GREEN);
|
||||||
$frame->core()->levelImage(0, $blue, $qrange['quantumRangeLong'], Imagick::CHANNEL_BLUE);
|
$frame->data()->levelImage(0, $blue, $qrange['quantumRangeLong'], Imagick::CHANNEL_BLUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $image;
|
return $image;
|
||||||
|
@@ -3,34 +3,23 @@
|
|||||||
namespace Intervention\Image\Drivers\Imagick\Modifiers;
|
namespace Intervention\Image\Drivers\Imagick\Modifiers;
|
||||||
|
|
||||||
use Imagick;
|
use Imagick;
|
||||||
use Intervention\Image\Colors\Cmyk\Colorspace as CmykColorspace;
|
use Intervention\Image\Drivers\DriverModifier;
|
||||||
use Intervention\Image\Colors\Rgb\Colorspace as RgbColorspace;
|
|
||||||
use Intervention\Image\Drivers\Imagick\Image;
|
|
||||||
use Intervention\Image\Exceptions\NotSupportedException;
|
use Intervention\Image\Exceptions\NotSupportedException;
|
||||||
use Intervention\Image\Interfaces\ColorspaceInterface;
|
use Intervention\Image\Interfaces\ColorspaceInterface;
|
||||||
use Intervention\Image\Interfaces\ImageInterface;
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
use Intervention\Image\Interfaces\ModifierInterface;
|
|
||||||
use Intervention\Image\Traits\CanCheckType;
|
|
||||||
|
|
||||||
class ColorspaceModifier implements ModifierInterface
|
class ColorspaceModifier extends DriverModifier
|
||||||
{
|
{
|
||||||
use CanCheckType;
|
|
||||||
|
|
||||||
protected static $mapping = [
|
protected static $mapping = [
|
||||||
RgbColorspace::class => Imagick::COLORSPACE_SRGB,
|
RgbColorspace::class => Imagick::COLORSPACE_SRGB,
|
||||||
CmykColorspace::class => Imagick::COLORSPACE_CMYK,
|
CmykColorspace::class => Imagick::COLORSPACE_CMYK,
|
||||||
];
|
];
|
||||||
|
|
||||||
public function __construct(protected string|ColorspaceInterface $target)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
public function apply(ImageInterface $image): ImageInterface
|
public function apply(ImageInterface $image): ImageInterface
|
||||||
{
|
{
|
||||||
$colorspace = $this->targetColorspace();
|
$colorspace = $this->targetColorspace();
|
||||||
|
|
||||||
$imagick = $this->failIfNotClass($image, Image::class)->getImagick();
|
$imagick = $image->core()->native();
|
||||||
$imagick->transformImageColorspace(
|
$imagick->transformImageColorspace(
|
||||||
$this->getImagickColorspace($colorspace)
|
$this->getImagickColorspace($colorspace)
|
||||||
);
|
);
|
||||||
@@ -46,21 +35,4 @@ class ColorspaceModifier implements ModifierInterface
|
|||||||
|
|
||||||
return self::$mapping[get_class($colorspace)];
|
return self::$mapping[get_class($colorspace)];
|
||||||
}
|
}
|
||||||
|
|
||||||
private function targetColorspace(): ColorspaceInterface
|
|
||||||
{
|
|
||||||
if (is_object($this->target)) {
|
|
||||||
return $this->target;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (in_array($this->target, ['rgb', 'RGB', RgbColorspace::class])) {
|
|
||||||
return new RgbColorspace();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (in_array($this->target, ['cmyk', 'CMYK', CmykColorspace::class])) {
|
|
||||||
return new CmykColorspace();
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new NotSupportedException('Given colorspace is not supported.');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -2,20 +2,15 @@
|
|||||||
|
|
||||||
namespace Intervention\Image\Drivers\Imagick\Modifiers;
|
namespace Intervention\Image\Drivers\Imagick\Modifiers;
|
||||||
|
|
||||||
|
use Intervention\Image\Drivers\DriverModifier;
|
||||||
use Intervention\Image\Interfaces\ImageInterface;
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
use Intervention\Image\Interfaces\ModifierInterface;
|
|
||||||
|
|
||||||
class ContrastModifier implements ModifierInterface
|
class ContrastModifier extends DriverModifier
|
||||||
{
|
{
|
||||||
public function __construct(protected int $level)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
public function apply(ImageInterface $image): ImageInterface
|
public function apply(ImageInterface $image): ImageInterface
|
||||||
{
|
{
|
||||||
foreach ($image as $frame) {
|
foreach ($image as $frame) {
|
||||||
$frame->core()->sigmoidalContrastImage($this->level > 0, abs($this->level / 4), 0);
|
$frame->data()->sigmoidalContrastImage($this->level > 0, abs($this->level / 4), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $image;
|
return $image;
|
||||||
|
@@ -2,30 +2,17 @@
|
|||||||
|
|
||||||
namespace Intervention\Image\Drivers\Imagick\Modifiers;
|
namespace Intervention\Image\Drivers\Imagick\Modifiers;
|
||||||
|
|
||||||
use Intervention\Image\Geometry\Rectangle;
|
use Intervention\Image\Drivers\DriverModifier;
|
||||||
use Intervention\Image\Interfaces\ImageInterface;
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
use Intervention\Image\Interfaces\ModifierInterface;
|
|
||||||
|
|
||||||
class CropModifier implements ModifierInterface
|
class CropModifier extends DriverModifier
|
||||||
{
|
{
|
||||||
public function __construct(
|
|
||||||
protected int $width,
|
|
||||||
protected int $height,
|
|
||||||
protected int $offset_x = 0,
|
|
||||||
protected int $offset_y = 0,
|
|
||||||
protected string $position = 'top-left'
|
|
||||||
) {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
public function apply(ImageInterface $image): ImageInterface
|
public function apply(ImageInterface $image): ImageInterface
|
||||||
{
|
{
|
||||||
$crop = new Rectangle($this->width, $this->height);
|
$crop = $this->crop($image);
|
||||||
$crop->align($this->position);
|
|
||||||
$crop->alignPivotTo($image->size(), $this->position);
|
|
||||||
|
|
||||||
foreach ($image as $frame) {
|
foreach ($image as $frame) {
|
||||||
$frame->core()->extentImage(
|
$frame->data()->extentImage(
|
||||||
$crop->width(),
|
$crop->width(),
|
||||||
$crop->height(),
|
$crop->height(),
|
||||||
$crop->pivot()->x() + $this->offset_x,
|
$crop->pivot()->x() + $this->offset_x,
|
||||||
|
@@ -1,18 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Intervention\Image\Drivers\Imagick\Modifiers;
|
|
||||||
|
|
||||||
use Intervention\Image\Interfaces\ImageInterface;
|
|
||||||
use Intervention\Image\Interfaces\ModifierInterface;
|
|
||||||
|
|
||||||
class DestroyModifier implements ModifierInterface
|
|
||||||
{
|
|
||||||
public function apply(ImageInterface $image): ImageInterface
|
|
||||||
{
|
|
||||||
foreach ($image as $frame) {
|
|
||||||
$frame->core()->clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
return $image;
|
|
||||||
}
|
|
||||||
}
|
|
@@ -3,40 +3,44 @@
|
|||||||
namespace Intervention\Image\Drivers\Imagick\Modifiers;
|
namespace Intervention\Image\Drivers\Imagick\Modifiers;
|
||||||
|
|
||||||
use ImagickDraw;
|
use ImagickDraw;
|
||||||
use Intervention\Image\Drivers\Abstract\Modifiers\AbstractDrawModifier;
|
use Intervention\Image\Drivers\DrawModifier;
|
||||||
use Intervention\Image\Drivers\Imagick\Traits\CanHandleColors;
|
|
||||||
use Intervention\Image\Interfaces\ImageInterface;
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
use Intervention\Image\Interfaces\ModifierInterface;
|
|
||||||
|
|
||||||
class DrawEllipseModifier extends AbstractDrawModifier implements ModifierInterface
|
class DrawEllipseModifier extends DrawModifier
|
||||||
{
|
{
|
||||||
use CanHandleColors;
|
|
||||||
|
|
||||||
public function apply(ImageInterface $image): ImageInterface
|
public function apply(ImageInterface $image): ImageInterface
|
||||||
{
|
{
|
||||||
$colorspace = $image->colorspace();
|
$background_color = $this->driver()->colorToNative(
|
||||||
$background_color = $this->colorToPixel($this->getBackgroundColor(), $colorspace);
|
$this->backgroundColor(),
|
||||||
$border_color = $this->colorToPixel($this->getBorderColor(), $colorspace);
|
$image->colorspace()
|
||||||
|
);
|
||||||
|
|
||||||
return $image->mapFrames(function ($frame) use ($background_color, $border_color) {
|
$border_color = $this->driver()->colorToNative(
|
||||||
|
$this->borderColor(),
|
||||||
|
$image->colorspace()
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ($image as $frame) {
|
||||||
$drawing = new ImagickDraw();
|
$drawing = new ImagickDraw();
|
||||||
$drawing->setFillColor($background_color);
|
$drawing->setFillColor($background_color);
|
||||||
|
|
||||||
if ($this->ellipse()->hasBorder()) {
|
if ($this->drawable->hasBorder()) {
|
||||||
$drawing->setStrokeWidth($this->ellipse()->getBorderSize());
|
$drawing->setStrokeWidth($this->drawable->borderSize());
|
||||||
$drawing->setStrokeColor($border_color);
|
$drawing->setStrokeColor($border_color);
|
||||||
}
|
}
|
||||||
|
|
||||||
$drawing->ellipse(
|
$drawing->ellipse(
|
||||||
$this->position->x(),
|
$this->position()->x(),
|
||||||
$this->position->y(),
|
$this->position()->y(),
|
||||||
$this->ellipse()->getWidth() / 2,
|
$this->drawable->width() / 2,
|
||||||
$this->ellipse()->getHeight() / 2,
|
$this->drawable->height() / 2,
|
||||||
0,
|
0,
|
||||||
360
|
360
|
||||||
);
|
);
|
||||||
|
|
||||||
$frame->core()->drawImage($drawing);
|
$frame->data()->drawImage($drawing);
|
||||||
});
|
}
|
||||||
|
|
||||||
|
return $image;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -3,32 +3,33 @@
|
|||||||
namespace Intervention\Image\Drivers\Imagick\Modifiers;
|
namespace Intervention\Image\Drivers\Imagick\Modifiers;
|
||||||
|
|
||||||
use ImagickDraw;
|
use ImagickDraw;
|
||||||
use Intervention\Image\Drivers\Abstract\Modifiers\AbstractDrawModifier;
|
use Intervention\Image\Drivers\DrawModifier;
|
||||||
use Intervention\Image\Drivers\Imagick\Traits\CanHandleColors;
|
|
||||||
use Intervention\Image\Interfaces\ImageInterface;
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
use Intervention\Image\Interfaces\ModifierInterface;
|
|
||||||
|
|
||||||
class DrawLineModifier extends AbstractDrawModifier implements ModifierInterface
|
class DrawLineModifier extends DrawModifier
|
||||||
{
|
{
|
||||||
use CanHandleColors;
|
|
||||||
|
|
||||||
public function apply(ImageInterface $image): ImageInterface
|
public function apply(ImageInterface $image): ImageInterface
|
||||||
{
|
{
|
||||||
$drawing = new ImagickDraw();
|
$drawing = new ImagickDraw();
|
||||||
$drawing->setStrokeWidth($this->line()->getWidth());
|
$drawing->setStrokeWidth($this->drawable->getWidth());
|
||||||
$drawing->setStrokeColor(
|
$drawing->setStrokeColor(
|
||||||
$this->colorToPixel($this->getBackgroundColor(), $image->colorspace())
|
$this->driver()->colorToNative(
|
||||||
|
$this->backgroundColor(),
|
||||||
|
$image->colorspace()
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
$drawing->line(
|
$drawing->line(
|
||||||
$this->line()->getStart()->x(),
|
$this->drawable->getStart()->x(),
|
||||||
$this->line()->getStart()->y(),
|
$this->drawable->getStart()->y(),
|
||||||
$this->line()->getEnd()->x(),
|
$this->drawable->getEnd()->x(),
|
||||||
$this->line()->getEnd()->y(),
|
$this->drawable->getEnd()->y(),
|
||||||
);
|
);
|
||||||
|
|
||||||
return $image->mapFrames(function ($frame) use ($drawing) {
|
foreach ($image as $frame) {
|
||||||
$frame->core()->drawImage($drawing);
|
$frame->data()->drawImage($drawing);
|
||||||
});
|
}
|
||||||
|
|
||||||
|
return $image;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -3,38 +3,26 @@
|
|||||||
namespace Intervention\Image\Drivers\Imagick\Modifiers;
|
namespace Intervention\Image\Drivers\Imagick\Modifiers;
|
||||||
|
|
||||||
use ImagickDraw;
|
use ImagickDraw;
|
||||||
use Intervention\Image\Drivers\Imagick\Traits\CanHandleColors;
|
use Intervention\Image\Drivers\DriverModifier;
|
||||||
use Intervention\Image\Geometry\Point;
|
|
||||||
use Intervention\Image\Interfaces\ColorInterface;
|
|
||||||
use Intervention\Image\Interfaces\ImageInterface;
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
use Intervention\Image\Interfaces\ModifierInterface;
|
|
||||||
use Intervention\Image\Traits\CanCheckType;
|
|
||||||
use Intervention\Image\Traits\CanHandleInput;
|
|
||||||
|
|
||||||
class DrawPixelModifier implements ModifierInterface
|
class DrawPixelModifier extends DriverModifier
|
||||||
{
|
{
|
||||||
use CanHandleInput;
|
|
||||||
use CanHandleColors;
|
|
||||||
use CanCheckType;
|
|
||||||
|
|
||||||
public function __construct(protected Point $position, protected mixed $color)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
public function apply(ImageInterface $image): ImageInterface
|
public function apply(ImageInterface $image): ImageInterface
|
||||||
{
|
{
|
||||||
$color = $this->failIfNotInstance(
|
$color = $this->driver()->colorToNative(
|
||||||
$this->handleInput($this->color),
|
$this->driver()->handleInput($this->color),
|
||||||
ColorInterface::class
|
$image->colorspace()
|
||||||
);
|
);
|
||||||
|
|
||||||
$pixel = new ImagickDraw();
|
$pixel = new ImagickDraw();
|
||||||
$pixel->setFillColor($this->colorToPixel($color, $image->colorspace()));
|
$pixel->setFillColor($color);
|
||||||
$pixel->point($this->position->x(), $this->position->y());
|
$pixel->point($this->position->x(), $this->position->y());
|
||||||
|
|
||||||
return $image->mapFrames(function ($frame) use ($pixel) {
|
foreach ($image as $frame) {
|
||||||
$frame->core()->drawImage($pixel);
|
$frame->data()->drawImage($pixel);
|
||||||
});
|
}
|
||||||
|
|
||||||
|
return $image;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -3,49 +3,47 @@
|
|||||||
namespace Intervention\Image\Drivers\Imagick\Modifiers;
|
namespace Intervention\Image\Drivers\Imagick\Modifiers;
|
||||||
|
|
||||||
use ImagickDraw;
|
use ImagickDraw;
|
||||||
use Intervention\Image\Drivers\Abstract\Modifiers\AbstractDrawModifier;
|
use Intervention\Image\Drivers\DrawModifier;
|
||||||
use Intervention\Image\Drivers\Imagick\Traits\CanHandleColors;
|
|
||||||
use Intervention\Image\Interfaces\DrawableInterface;
|
|
||||||
use Intervention\Image\Interfaces\ImageInterface;
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
use Intervention\Image\Interfaces\ModifierInterface;
|
|
||||||
|
|
||||||
class DrawPolygonModifier extends AbstractDrawModifier implements ModifierInterface
|
class DrawPolygonModifier extends DrawModifier
|
||||||
{
|
{
|
||||||
use CanHandleColors;
|
|
||||||
|
|
||||||
public function __construct(
|
|
||||||
protected DrawableInterface $drawable
|
|
||||||
) {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
public function apply(ImageInterface $image): ImageInterface
|
public function apply(ImageInterface $image): ImageInterface
|
||||||
{
|
{
|
||||||
$drawing = new ImagickDraw();
|
$drawing = new ImagickDraw();
|
||||||
$colorspace = $image->colorspace();
|
|
||||||
$background_color = $this->colorToPixel($this->getBackgroundColor(), $colorspace);
|
|
||||||
$border_color = $this->colorToPixel($this->getBorderColor(), $colorspace);
|
|
||||||
|
|
||||||
if ($this->polygon()->hasBackgroundColor()) {
|
if ($this->drawable->hasBackgroundColor()) {
|
||||||
|
$background_color = $this->driver()->colorToNative(
|
||||||
|
$this->backgroundColor(),
|
||||||
|
$image->colorspace()
|
||||||
|
);
|
||||||
|
|
||||||
$drawing->setFillColor($background_color);
|
$drawing->setFillColor($background_color);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->polygon()->hasBorder()) {
|
if ($this->drawable->hasBorder()) {
|
||||||
|
$border_color = $this->driver()->colorToNative(
|
||||||
|
$this->borderColor(),
|
||||||
|
$image->colorspace()
|
||||||
|
);
|
||||||
|
|
||||||
$drawing->setStrokeColor($border_color);
|
$drawing->setStrokeColor($border_color);
|
||||||
$drawing->setStrokeWidth($this->polygon()->getBorderSize());
|
$drawing->setStrokeWidth($this->drawable->borderSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
$drawing->polygon($this->points());
|
$drawing->polygon($this->points());
|
||||||
|
|
||||||
return $image->mapFrames(function ($frame) use ($drawing) {
|
foreach ($image as $frame) {
|
||||||
$frame->core()->drawImage($drawing);
|
$frame->data()->drawImage($drawing);
|
||||||
});
|
}
|
||||||
|
|
||||||
|
return $image;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function points(): array
|
private function points(): array
|
||||||
{
|
{
|
||||||
$points = [];
|
$points = [];
|
||||||
foreach ($this->polygon() as $point) {
|
foreach ($this->drawable as $point) {
|
||||||
$points[] = ['x' => $point->x(), 'y' => $point->y()];
|
$points[] = ['x' => $point->x(), 'y' => $point->y()];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user