charger une image
This commit is contained in:
12
upLoadImage/vendor/intervention/image/src/Analyzers/ColorspaceAnalyzer.php
vendored
Normal file
12
upLoadImage/vendor/intervention/image/src/Analyzers/ColorspaceAnalyzer.php
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Analyzers;
|
||||
|
||||
use Intervention\Image\Drivers\SpecializableAnalyzer;
|
||||
|
||||
class ColorspaceAnalyzer extends SpecializableAnalyzer
|
||||
{
|
||||
//
|
||||
}
|
||||
12
upLoadImage/vendor/intervention/image/src/Analyzers/HeightAnalyzer.php
vendored
Normal file
12
upLoadImage/vendor/intervention/image/src/Analyzers/HeightAnalyzer.php
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Analyzers;
|
||||
|
||||
use Intervention\Image\Drivers\SpecializableAnalyzer;
|
||||
|
||||
class HeightAnalyzer extends SpecializableAnalyzer
|
||||
{
|
||||
//
|
||||
}
|
||||
18
upLoadImage/vendor/intervention/image/src/Analyzers/PixelColorAnalyzer.php
vendored
Normal file
18
upLoadImage/vendor/intervention/image/src/Analyzers/PixelColorAnalyzer.php
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Analyzers;
|
||||
|
||||
use Intervention\Image\Drivers\SpecializableAnalyzer;
|
||||
|
||||
class PixelColorAnalyzer extends SpecializableAnalyzer
|
||||
{
|
||||
public function __construct(
|
||||
public int $x,
|
||||
public int $y,
|
||||
public int $frame_key = 0
|
||||
) {
|
||||
//
|
||||
}
|
||||
}
|
||||
17
upLoadImage/vendor/intervention/image/src/Analyzers/PixelColorsAnalyzer.php
vendored
Normal file
17
upLoadImage/vendor/intervention/image/src/Analyzers/PixelColorsAnalyzer.php
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Analyzers;
|
||||
|
||||
use Intervention\Image\Drivers\SpecializableAnalyzer;
|
||||
|
||||
class PixelColorsAnalyzer extends SpecializableAnalyzer
|
||||
{
|
||||
public function __construct(
|
||||
public int $x,
|
||||
public int $y
|
||||
) {
|
||||
//
|
||||
}
|
||||
}
|
||||
12
upLoadImage/vendor/intervention/image/src/Analyzers/ProfileAnalyzer.php
vendored
Normal file
12
upLoadImage/vendor/intervention/image/src/Analyzers/ProfileAnalyzer.php
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Analyzers;
|
||||
|
||||
use Intervention\Image\Drivers\SpecializableAnalyzer;
|
||||
|
||||
class ProfileAnalyzer extends SpecializableAnalyzer
|
||||
{
|
||||
//
|
||||
}
|
||||
12
upLoadImage/vendor/intervention/image/src/Analyzers/ResolutionAnalyzer.php
vendored
Normal file
12
upLoadImage/vendor/intervention/image/src/Analyzers/ResolutionAnalyzer.php
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Analyzers;
|
||||
|
||||
use Intervention\Image\Drivers\SpecializableAnalyzer;
|
||||
|
||||
class ResolutionAnalyzer extends SpecializableAnalyzer
|
||||
{
|
||||
//
|
||||
}
|
||||
12
upLoadImage/vendor/intervention/image/src/Analyzers/WidthAnalyzer.php
vendored
Normal file
12
upLoadImage/vendor/intervention/image/src/Analyzers/WidthAnalyzer.php
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Analyzers;
|
||||
|
||||
use Intervention\Image\Drivers\SpecializableAnalyzer;
|
||||
|
||||
class WidthAnalyzer extends SpecializableAnalyzer
|
||||
{
|
||||
//
|
||||
}
|
||||
217
upLoadImage/vendor/intervention/image/src/Collection.php
vendored
Normal file
217
upLoadImage/vendor/intervention/image/src/Collection.php
vendored
Normal file
@@ -0,0 +1,217 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image;
|
||||
|
||||
use Intervention\Image\Interfaces\CollectionInterface;
|
||||
use ArrayIterator;
|
||||
use Countable;
|
||||
use Traversable;
|
||||
use IteratorAggregate;
|
||||
|
||||
/**
|
||||
* @implements IteratorAggregate<int|string, mixed>
|
||||
*/
|
||||
class Collection implements CollectionInterface, IteratorAggregate, Countable
|
||||
{
|
||||
/**
|
||||
* Create new collection object
|
||||
*
|
||||
* @param array<int|string, mixed> $items
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(protected array $items = [])
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Static constructor
|
||||
*
|
||||
* @param array<int|string, mixed> $items
|
||||
* @return self<int|string, mixed>
|
||||
*/
|
||||
public static function create(array $items = []): self
|
||||
{
|
||||
return new self($items);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see CollectionInterface::has()
|
||||
*/
|
||||
public function has(int|string $key): bool
|
||||
{
|
||||
return array_key_exists($key, $this->items);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns Iterator
|
||||
*
|
||||
* @return Traversable<int|string, mixed>
|
||||
*/
|
||||
public function getIterator(): Traversable
|
||||
{
|
||||
return new ArrayIterator($this->items);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see CollectionInterface::toArray()
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
return $this->items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Count items in collection
|
||||
*/
|
||||
public function count(): int
|
||||
{
|
||||
return count($this->items);
|
||||
}
|
||||
|
||||
/**
|
||||
* Append new item to collection
|
||||
*
|
||||
* @return CollectionInterface<int|string, mixed>
|
||||
*/
|
||||
public function push(mixed $item): CollectionInterface
|
||||
{
|
||||
$this->items[] = $item;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return first item in collection
|
||||
*/
|
||||
public function first(): mixed
|
||||
{
|
||||
if ($item = reset($this->items)) {
|
||||
return $item;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns last item in collection
|
||||
*/
|
||||
public function last(): mixed
|
||||
{
|
||||
if ($item = end($this->items)) {
|
||||
return $item;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return item at given position starting at 0
|
||||
*/
|
||||
public function getAtPosition(int $key = 0, mixed $default = null): mixed
|
||||
{
|
||||
if ($this->count() == 0) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
$positions = array_values($this->items);
|
||||
if (!array_key_exists($key, $positions)) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
return $positions[$key];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see CollectionInterface::get()
|
||||
*/
|
||||
public function get(int|string $query, mixed $default = null): mixed
|
||||
{
|
||||
if ($this->count() == 0) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
if (is_int($query) && array_key_exists($query, $this->items)) {
|
||||
return $this->items[$query];
|
||||
}
|
||||
|
||||
if (is_string($query) && !str_contains($query, '.')) {
|
||||
return array_key_exists($query, $this->items) ? $this->items[$query] : $default;
|
||||
}
|
||||
|
||||
$query = explode('.', (string) $query);
|
||||
|
||||
$result = $default;
|
||||
$items = $this->items;
|
||||
foreach ($query as $key) {
|
||||
if (!is_array($items) || !array_key_exists($key, $items)) {
|
||||
$result = $default;
|
||||
break;
|
||||
}
|
||||
|
||||
$result = $items[$key];
|
||||
$items = $result;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Map each item of collection by given callback
|
||||
*/
|
||||
public function map(callable $callback): self
|
||||
{
|
||||
|
||||
return new self(
|
||||
array_map(
|
||||
fn(mixed $item) => $callback($item),
|
||||
$this->items,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Run callback on each item of the collection an remove it if it does not return true
|
||||
*/
|
||||
public function filter(callable $callback): self
|
||||
{
|
||||
return new self(
|
||||
array_filter(
|
||||
$this->items,
|
||||
fn(mixed $item) => $callback($item),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see CollectionInterface::empty()
|
||||
*/
|
||||
public function empty(): CollectionInterface
|
||||
{
|
||||
$this->items = [];
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see CollectionInterface::slice()
|
||||
*/
|
||||
public function slice(int $offset, ?int $length = null): CollectionInterface
|
||||
{
|
||||
$this->items = array_slice($this->items, $offset, $length);
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
116
upLoadImage/vendor/intervention/image/src/Colors/AbstractColor.php
vendored
Normal file
116
upLoadImage/vendor/intervention/image/src/Colors/AbstractColor.php
vendored
Normal file
@@ -0,0 +1,116 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Colors;
|
||||
|
||||
use Intervention\Image\Exceptions\ColorException;
|
||||
use Intervention\Image\Interfaces\ColorChannelInterface;
|
||||
use Intervention\Image\Interfaces\ColorInterface;
|
||||
use Intervention\Image\Interfaces\ColorspaceInterface;
|
||||
use ReflectionClass;
|
||||
use Stringable;
|
||||
|
||||
abstract class AbstractColor implements ColorInterface, Stringable
|
||||
{
|
||||
/**
|
||||
* Color channels
|
||||
*
|
||||
* @var array<ColorChannelInterface>
|
||||
*/
|
||||
protected array $channels;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see ColorInterface::channels()
|
||||
*/
|
||||
public function channels(): array
|
||||
{
|
||||
return $this->channels;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see ColorInterface::channel()
|
||||
*/
|
||||
public function channel(string $classname): ColorChannelInterface
|
||||
{
|
||||
$channels = array_filter(
|
||||
$this->channels(),
|
||||
fn(ColorChannelInterface $channel): bool => $channel::class === $classname,
|
||||
);
|
||||
|
||||
if (count($channels) == 0) {
|
||||
throw new ColorException('Color channel ' . $classname . ' could not be found.');
|
||||
}
|
||||
|
||||
return reset($channels);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see ColorInterface::normalize()
|
||||
*/
|
||||
public function normalize(): array
|
||||
{
|
||||
return array_map(
|
||||
fn(ColorChannelInterface $channel): float => $channel->normalize(),
|
||||
$this->channels(),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see ColorInterface::toArray()
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
return array_map(
|
||||
fn(ColorChannelInterface $channel): int => $channel->value(),
|
||||
$this->channels()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see ColorInterface::convertTo()
|
||||
*/
|
||||
public function convertTo(string|ColorspaceInterface $colorspace): ColorInterface
|
||||
{
|
||||
$colorspace = match (true) {
|
||||
is_object($colorspace) => $colorspace,
|
||||
default => new $colorspace(),
|
||||
};
|
||||
|
||||
return $colorspace->importColor($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show debug info for the current color
|
||||
*
|
||||
* @return array<string, int>
|
||||
*/
|
||||
public function __debugInfo(): array
|
||||
{
|
||||
return array_reduce($this->channels(), function (array $result, ColorChannelInterface $item) {
|
||||
$key = strtolower((new ReflectionClass($item))->getShortName());
|
||||
$result[$key] = $item->value();
|
||||
return $result;
|
||||
}, []);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see ColorInterface::__toString()
|
||||
*/
|
||||
public function __toString(): string
|
||||
{
|
||||
return $this->toString();
|
||||
}
|
||||
}
|
||||
92
upLoadImage/vendor/intervention/image/src/Colors/AbstractColorChannel.php
vendored
Normal file
92
upLoadImage/vendor/intervention/image/src/Colors/AbstractColorChannel.php
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Colors;
|
||||
|
||||
use Intervention\Image\Exceptions\ColorException;
|
||||
use Intervention\Image\Interfaces\ColorChannelInterface;
|
||||
use Stringable;
|
||||
|
||||
abstract class AbstractColorChannel implements ColorChannelInterface, Stringable
|
||||
{
|
||||
protected int $value;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see ColorChannelInterface::__construct()
|
||||
*/
|
||||
public function __construct(?int $value = null, ?float $normalized = null)
|
||||
{
|
||||
$this->value = $this->validate(
|
||||
match (true) {
|
||||
is_null($value) && is_numeric($normalized) => intval(round($normalized * $this->max())),
|
||||
is_numeric($value) && is_null($normalized) => $value,
|
||||
default => throw new ColorException('Color channels must either have a value or a normalized value')
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Alias of value()
|
||||
*/
|
||||
public function toInt(): int
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see ColorChannelInterface::value()
|
||||
*/
|
||||
public function value(): int
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see ColorChannelInterface::normalize()
|
||||
*/
|
||||
public function normalize(int $precision = 32): float
|
||||
{
|
||||
return round(($this->value() - $this->min()) / ($this->max() - $this->min()), $precision);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see ColorChannelInterface::validate()
|
||||
*/
|
||||
public function validate(mixed $value): mixed
|
||||
{
|
||||
if ($value < $this->min() || $value > $this->max()) {
|
||||
throw new ColorException('Color channel value must be in range ' . $this->min() . ' to ' . $this->max());
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see ColorChannelInterface::toString()
|
||||
*/
|
||||
public function toString(): string
|
||||
{
|
||||
return (string) $this->value();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see ColorChannelInterface::__toString()
|
||||
*/
|
||||
public function __toString(): string
|
||||
{
|
||||
return $this->toString();
|
||||
}
|
||||
}
|
||||
20
upLoadImage/vendor/intervention/image/src/Colors/Cmyk/Channels/Cyan.php
vendored
Normal file
20
upLoadImage/vendor/intervention/image/src/Colors/Cmyk/Channels/Cyan.php
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Colors\Cmyk\Channels;
|
||||
|
||||
use Intervention\Image\Colors\AbstractColorChannel;
|
||||
|
||||
class Cyan extends AbstractColorChannel
|
||||
{
|
||||
public function min(): int
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function max(): int
|
||||
{
|
||||
return 100;
|
||||
}
|
||||
}
|
||||
10
upLoadImage/vendor/intervention/image/src/Colors/Cmyk/Channels/Key.php
vendored
Normal file
10
upLoadImage/vendor/intervention/image/src/Colors/Cmyk/Channels/Key.php
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Colors\Cmyk\Channels;
|
||||
|
||||
class Key extends Cyan
|
||||
{
|
||||
//
|
||||
}
|
||||
10
upLoadImage/vendor/intervention/image/src/Colors/Cmyk/Channels/Magenta.php
vendored
Normal file
10
upLoadImage/vendor/intervention/image/src/Colors/Cmyk/Channels/Magenta.php
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Colors\Cmyk\Channels;
|
||||
|
||||
class Magenta extends Cyan
|
||||
{
|
||||
//
|
||||
}
|
||||
10
upLoadImage/vendor/intervention/image/src/Colors/Cmyk/Channels/Yellow.php
vendored
Normal file
10
upLoadImage/vendor/intervention/image/src/Colors/Cmyk/Channels/Yellow.php
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Colors\Cmyk\Channels;
|
||||
|
||||
class Yellow extends Cyan
|
||||
{
|
||||
//
|
||||
}
|
||||
153
upLoadImage/vendor/intervention/image/src/Colors/Cmyk/Color.php
vendored
Normal file
153
upLoadImage/vendor/intervention/image/src/Colors/Cmyk/Color.php
vendored
Normal file
@@ -0,0 +1,153 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Colors\Cmyk;
|
||||
|
||||
use Intervention\Image\Colors\AbstractColor;
|
||||
use Intervention\Image\Colors\Cmyk\Channels\Cyan;
|
||||
use Intervention\Image\Colors\Cmyk\Channels\Magenta;
|
||||
use Intervention\Image\Colors\Cmyk\Channels\Yellow;
|
||||
use Intervention\Image\Colors\Cmyk\Channels\Key;
|
||||
use Intervention\Image\Colors\Rgb\Colorspace as RgbColorspace;
|
||||
use Intervention\Image\InputHandler;
|
||||
use Intervention\Image\Interfaces\ColorChannelInterface;
|
||||
use Intervention\Image\Interfaces\ColorInterface;
|
||||
use Intervention\Image\Interfaces\ColorspaceInterface;
|
||||
|
||||
class Color extends AbstractColor
|
||||
{
|
||||
/**
|
||||
* Create new instance
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(int $c, int $m, int $y, int $k)
|
||||
{
|
||||
/** @throws void */
|
||||
$this->channels = [
|
||||
new Cyan($c),
|
||||
new Magenta($m),
|
||||
new Yellow($y),
|
||||
new Key($k),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see ColorInterface::create()
|
||||
*/
|
||||
public static function create(mixed $input): ColorInterface
|
||||
{
|
||||
return InputHandler::withDecoders([
|
||||
Decoders\StringColorDecoder::class,
|
||||
])->handle($input);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see ColorInterface::colorspace()
|
||||
*/
|
||||
public function colorspace(): ColorspaceInterface
|
||||
{
|
||||
return new Colorspace();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see ColorInterface::toHex()
|
||||
*/
|
||||
public function toHex(string $prefix = ''): string
|
||||
{
|
||||
return $this->convertTo(RgbColorspace::class)->toHex($prefix);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the CMYK cyan channel
|
||||
*/
|
||||
public function cyan(): ColorChannelInterface
|
||||
{
|
||||
/** @throws void */
|
||||
return $this->channel(Cyan::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the CMYK magenta channel
|
||||
*/
|
||||
public function magenta(): ColorChannelInterface
|
||||
{
|
||||
/** @throws void */
|
||||
return $this->channel(Magenta::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the CMYK yellow channel
|
||||
*/
|
||||
public function yellow(): ColorChannelInterface
|
||||
{
|
||||
/** @throws void */
|
||||
return $this->channel(Yellow::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the CMYK key channel
|
||||
*/
|
||||
public function key(): ColorChannelInterface
|
||||
{
|
||||
/** @throws void */
|
||||
return $this->channel(Key::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see ColorInterface::toString()
|
||||
*/
|
||||
public function toString(): string
|
||||
{
|
||||
return sprintf(
|
||||
'cmyk(%d%%, %d%%, %d%%, %d%%)',
|
||||
$this->cyan()->value(),
|
||||
$this->magenta()->value(),
|
||||
$this->yellow()->value(),
|
||||
$this->key()->value()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see ColorInterface::isGreyscale()
|
||||
*/
|
||||
public function isGreyscale(): bool
|
||||
{
|
||||
return 0 === array_sum([
|
||||
$this->cyan()->value(),
|
||||
$this->magenta()->value(),
|
||||
$this->yellow()->value(),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see ColorInterface::isTransparent()
|
||||
*/
|
||||
public function isTransparent(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see ColorInterface::isClear()
|
||||
*/
|
||||
public function isClear(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
77
upLoadImage/vendor/intervention/image/src/Colors/Cmyk/Colorspace.php
vendored
Normal file
77
upLoadImage/vendor/intervention/image/src/Colors/Cmyk/Colorspace.php
vendored
Normal file
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Colors\Cmyk;
|
||||
|
||||
use Intervention\Image\Colors\Rgb\Color as RgbColor;
|
||||
use Intervention\Image\Colors\Cmyk\Color as CmykColor;
|
||||
use Intervention\Image\Colors\Hsv\Color as HsvColor;
|
||||
use Intervention\Image\Colors\Hsl\Color as HslColor;
|
||||
use Intervention\Image\Colors\Rgb\Colorspace as RgbColorspace;
|
||||
use Intervention\Image\Exceptions\ColorException;
|
||||
use Intervention\Image\Interfaces\ColorInterface;
|
||||
use Intervention\Image\Interfaces\ColorspaceInterface;
|
||||
|
||||
class Colorspace implements ColorspaceInterface
|
||||
{
|
||||
/**
|
||||
* Channel class names of colorspace
|
||||
*
|
||||
* @var array<string>
|
||||
*/
|
||||
public static array $channels = [
|
||||
Channels\Cyan::class,
|
||||
Channels\Magenta::class,
|
||||
Channels\Yellow::class,
|
||||
Channels\Key::class
|
||||
];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see ColorspaceInterface::createColor()
|
||||
*/
|
||||
public function colorFromNormalized(array $normalized): ColorInterface
|
||||
{
|
||||
return new Color(...array_map(
|
||||
fn(string $classname, float $value_normalized) => (new $classname(normalized: $value_normalized))->value(),
|
||||
self::$channels,
|
||||
$normalized,
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ColorException
|
||||
*/
|
||||
public function importColor(ColorInterface $color): ColorInterface
|
||||
{
|
||||
return match ($color::class) {
|
||||
RgbColor::class => $this->importRgbColor($color),
|
||||
HsvColor::class => $this->importRgbColor($color->convertTo(RgbColorspace::class)),
|
||||
HslColor::class => $this->importRgbColor($color->convertTo(RgbColorspace::class)),
|
||||
default => $color,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ColorException
|
||||
*/
|
||||
protected function importRgbColor(ColorInterface $color): CmykColor
|
||||
{
|
||||
if (!($color instanceof RgbColor)) {
|
||||
throw new ColorException('Unabled to import color of type ' . $color::class . '.');
|
||||
}
|
||||
|
||||
$c = (255 - $color->red()->value()) / 255.0 * 100;
|
||||
$m = (255 - $color->green()->value()) / 255.0 * 100;
|
||||
$y = (255 - $color->blue()->value()) / 255.0 * 100;
|
||||
$k = intval(round(min([$c, $m, $y])));
|
||||
|
||||
$c = intval(round($c - $k));
|
||||
$m = intval(round($m - $k));
|
||||
$y = intval(round($y - $k));
|
||||
|
||||
return new CmykColor($c, $m, $y, $k);
|
||||
}
|
||||
}
|
||||
36
upLoadImage/vendor/intervention/image/src/Colors/Cmyk/Decoders/StringColorDecoder.php
vendored
Normal file
36
upLoadImage/vendor/intervention/image/src/Colors/Cmyk/Decoders/StringColorDecoder.php
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Colors\Cmyk\Decoders;
|
||||
|
||||
use Intervention\Image\Colors\Cmyk\Color;
|
||||
use Intervention\Image\Drivers\AbstractDecoder;
|
||||
use Intervention\Image\Exceptions\DecoderException;
|
||||
use Intervention\Image\Interfaces\ColorInterface;
|
||||
use Intervention\Image\Interfaces\DecoderInterface;
|
||||
use Intervention\Image\Interfaces\ImageInterface;
|
||||
|
||||
class StringColorDecoder extends AbstractDecoder implements DecoderInterface
|
||||
{
|
||||
/**
|
||||
* Decode CMYK color strings
|
||||
*/
|
||||
public function decode(mixed $input): ImageInterface|ColorInterface
|
||||
{
|
||||
if (!is_string($input)) {
|
||||
throw new DecoderException('Unable to decode input');
|
||||
}
|
||||
|
||||
$pattern = '/^cmyk\((?P<c>[0-9\.]+%?), ?(?P<m>[0-9\.]+%?), ?(?P<y>[0-9\.]+%?), ?(?P<k>[0-9\.]+%?)\)$/i';
|
||||
if (preg_match($pattern, $input, $matches) != 1) {
|
||||
throw new DecoderException('Unable to decode input');
|
||||
}
|
||||
|
||||
$values = array_map(function (string $value): int {
|
||||
return intval(round(floatval(trim(str_replace('%', '', $value)))));
|
||||
}, [$matches['c'], $matches['m'], $matches['y'], $matches['k']]);
|
||||
|
||||
return new Color(...$values);
|
||||
}
|
||||
}
|
||||
30
upLoadImage/vendor/intervention/image/src/Colors/Hsl/Channels/Hue.php
vendored
Normal file
30
upLoadImage/vendor/intervention/image/src/Colors/Hsl/Channels/Hue.php
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Colors\Hsl\Channels;
|
||||
|
||||
use Intervention\Image\Colors\AbstractColorChannel;
|
||||
|
||||
class Hue extends AbstractColorChannel
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see ColorChannelInterface::min()
|
||||
*/
|
||||
public function min(): int
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see ColorChannelInterface::max()
|
||||
*/
|
||||
public function max(): int
|
||||
{
|
||||
return 360;
|
||||
}
|
||||
}
|
||||
30
upLoadImage/vendor/intervention/image/src/Colors/Hsl/Channels/Luminance.php
vendored
Normal file
30
upLoadImage/vendor/intervention/image/src/Colors/Hsl/Channels/Luminance.php
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Colors\Hsl\Channels;
|
||||
|
||||
use Intervention\Image\Colors\AbstractColorChannel;
|
||||
|
||||
class Luminance extends AbstractColorChannel
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see ColorChannelInterface::min()
|
||||
*/
|
||||
public function min(): int
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see ColorChannelInterface::max()
|
||||
*/
|
||||
public function max(): int
|
||||
{
|
||||
return 100;
|
||||
}
|
||||
}
|
||||
30
upLoadImage/vendor/intervention/image/src/Colors/Hsl/Channels/Saturation.php
vendored
Normal file
30
upLoadImage/vendor/intervention/image/src/Colors/Hsl/Channels/Saturation.php
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Colors\Hsl\Channels;
|
||||
|
||||
use Intervention\Image\Colors\AbstractColorChannel;
|
||||
|
||||
class Saturation extends AbstractColorChannel
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see ColorChannelInterface::min()
|
||||
*/
|
||||
public function min(): int
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see ColorChannelInterface::max()
|
||||
*/
|
||||
public function max(): int
|
||||
{
|
||||
return 100;
|
||||
}
|
||||
}
|
||||
132
upLoadImage/vendor/intervention/image/src/Colors/Hsl/Color.php
vendored
Normal file
132
upLoadImage/vendor/intervention/image/src/Colors/Hsl/Color.php
vendored
Normal file
@@ -0,0 +1,132 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Colors\Hsl;
|
||||
|
||||
use Intervention\Image\Colors\AbstractColor;
|
||||
use Intervention\Image\Colors\Hsl\Channels\Hue;
|
||||
use Intervention\Image\Colors\Hsl\Channels\Luminance;
|
||||
use Intervention\Image\Colors\Hsl\Channels\Saturation;
|
||||
use Intervention\Image\Colors\Rgb\Colorspace as RgbColorspace;
|
||||
use Intervention\Image\InputHandler;
|
||||
use Intervention\Image\Interfaces\ColorChannelInterface;
|
||||
use Intervention\Image\Interfaces\ColorInterface;
|
||||
use Intervention\Image\Interfaces\ColorspaceInterface;
|
||||
|
||||
class Color extends AbstractColor
|
||||
{
|
||||
/**
|
||||
* Create new color object
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(int $h, int $s, int $l)
|
||||
{
|
||||
/** @throws void */
|
||||
$this->channels = [
|
||||
new Hue($h),
|
||||
new Saturation($s),
|
||||
new Luminance($l),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see ColorInterface::colorspace()
|
||||
*/
|
||||
public function colorspace(): ColorspaceInterface
|
||||
{
|
||||
return new Colorspace();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see ColorInterface::create()
|
||||
*/
|
||||
public static function create(mixed $input): ColorInterface
|
||||
{
|
||||
return InputHandler::withDecoders([
|
||||
Decoders\StringColorDecoder::class,
|
||||
])->handle($input);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the Hue channel
|
||||
*/
|
||||
public function hue(): ColorChannelInterface
|
||||
{
|
||||
/** @throws void */
|
||||
return $this->channel(Hue::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the Saturation channel
|
||||
*/
|
||||
public function saturation(): ColorChannelInterface
|
||||
{
|
||||
/** @throws void */
|
||||
return $this->channel(Saturation::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the Luminance channel
|
||||
*/
|
||||
public function luminance(): ColorChannelInterface
|
||||
{
|
||||
/** @throws void */
|
||||
return $this->channel(Luminance::class);
|
||||
}
|
||||
|
||||
public function toHex(string $prefix = ''): string
|
||||
{
|
||||
return $this->convertTo(RgbColorspace::class)->toHex($prefix);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see ColorInterface::toString()
|
||||
*/
|
||||
public function toString(): string
|
||||
{
|
||||
return sprintf(
|
||||
'hsl(%d, %d%%, %d%%)',
|
||||
$this->hue()->value(),
|
||||
$this->saturation()->value(),
|
||||
$this->luminance()->value()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see ColorInterface::isGreyscale()
|
||||
*/
|
||||
public function isGreyscale(): bool
|
||||
{
|
||||
return $this->saturation()->value() == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see ColorInterface::isTransparent()
|
||||
*/
|
||||
public function isTransparent(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see ColorInterface::isClear()
|
||||
*/
|
||||
public function isClear(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
137
upLoadImage/vendor/intervention/image/src/Colors/Hsl/Colorspace.php
vendored
Normal file
137
upLoadImage/vendor/intervention/image/src/Colors/Hsl/Colorspace.php
vendored
Normal file
@@ -0,0 +1,137 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Colors\Hsl;
|
||||
|
||||
use Intervention\Image\Colors\Cmyk\Color as CmykColor;
|
||||
use Intervention\Image\Colors\Rgb\Color as RgbColor;
|
||||
use Intervention\Image\Colors\Hsv\Color as HsvColor;
|
||||
use Intervention\Image\Colors\Rgb\Colorspace as RgbColorspace;
|
||||
use Intervention\Image\Exceptions\ColorException;
|
||||
use Intervention\Image\Interfaces\ColorChannelInterface;
|
||||
use Intervention\Image\Interfaces\ColorInterface;
|
||||
use Intervention\Image\Interfaces\ColorspaceInterface;
|
||||
|
||||
class Colorspace implements ColorspaceInterface
|
||||
{
|
||||
/**
|
||||
* Channel class names of colorspace
|
||||
*
|
||||
* @var array<string>
|
||||
*/
|
||||
public static array $channels = [
|
||||
Channels\Hue::class,
|
||||
Channels\Saturation::class,
|
||||
Channels\Luminance::class
|
||||
];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see ColorspaceInterface::colorFromNormalized()
|
||||
*/
|
||||
public function colorFromNormalized(array $normalized): ColorInterface
|
||||
{
|
||||
return new Color(...array_map(
|
||||
fn(string $classname, float $value_normalized) => (new $classname(normalized: $value_normalized))->value(),
|
||||
self::$channels,
|
||||
$normalized
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ColorException
|
||||
*/
|
||||
public function importColor(ColorInterface $color): ColorInterface
|
||||
{
|
||||
return match ($color::class) {
|
||||
CmykColor::class => $this->importRgbColor($color->convertTo(RgbColorspace::class)),
|
||||
RgbColor::class => $this->importRgbColor($color),
|
||||
HsvColor::class => $this->importHsvColor($color),
|
||||
default => $color,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ColorException
|
||||
*/
|
||||
protected function importRgbColor(ColorInterface $color): ColorInterface
|
||||
{
|
||||
if (!($color instanceof RgbColor)) {
|
||||
throw new ColorException('Unabled to import color of type ' . $color::class . '.');
|
||||
}
|
||||
|
||||
// normalized values of rgb channels
|
||||
$values = array_map(
|
||||
fn(ColorChannelInterface $channel): float => $channel->normalize(),
|
||||
$color->channels(),
|
||||
);
|
||||
|
||||
// take only RGB
|
||||
$values = array_slice($values, 0, 3);
|
||||
|
||||
// calculate Luminance
|
||||
$min = min(...$values);
|
||||
$max = max(...$values);
|
||||
$luminance = ($max + $min) / 2;
|
||||
$delta = $max - $min;
|
||||
|
||||
// calculate saturation
|
||||
$saturation = match (true) {
|
||||
$delta == 0 => 0,
|
||||
default => $delta / (1 - abs(2 * $luminance - 1)),
|
||||
};
|
||||
|
||||
// calculate hue
|
||||
[$r, $g, $b] = $values;
|
||||
$hue = match (true) {
|
||||
($delta == 0) => 0,
|
||||
($max == $r) => 60 * fmod((($g - $b) / $delta), 6),
|
||||
($max == $g) => 60 * ((($b - $r) / $delta) + 2),
|
||||
($max == $b) => 60 * ((($r - $g) / $delta) + 4),
|
||||
default => 0,
|
||||
};
|
||||
|
||||
$hue = ($hue + 360) % 360; // normalize hue
|
||||
|
||||
return new Color(
|
||||
intval(round($hue)),
|
||||
intval(round($saturation * 100)),
|
||||
intval(round($luminance * 100)),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ColorException
|
||||
*/
|
||||
protected function importHsvColor(ColorInterface $color): ColorInterface
|
||||
{
|
||||
if (!($color instanceof HsvColor)) {
|
||||
throw new ColorException('Unabled to import color of type ' . $color::class . '.');
|
||||
}
|
||||
|
||||
// normalized values of hsv channels
|
||||
[$h, $s, $v] = array_map(
|
||||
fn(ColorChannelInterface $channel): float => $channel->normalize(),
|
||||
$color->channels(),
|
||||
);
|
||||
|
||||
// calculate Luminance
|
||||
$luminance = (2 - $s) * $v / 2;
|
||||
|
||||
// calculate Saturation
|
||||
$saturation = match (true) {
|
||||
$luminance == 0 => $s,
|
||||
$luminance == 1 => 0,
|
||||
$luminance < .5 => $s * $v / ($luminance * 2),
|
||||
default => $s * $v / (2 - $luminance * 2),
|
||||
};
|
||||
|
||||
return new Color(
|
||||
intval(round($h * 360)),
|
||||
intval(round($saturation * 100)),
|
||||
intval(round($luminance * 100)),
|
||||
);
|
||||
}
|
||||
}
|
||||
39
upLoadImage/vendor/intervention/image/src/Colors/Hsl/Decoders/StringColorDecoder.php
vendored
Normal file
39
upLoadImage/vendor/intervention/image/src/Colors/Hsl/Decoders/StringColorDecoder.php
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Colors\Hsl\Decoders;
|
||||
|
||||
use Intervention\Image\Colors\Hsl\Color;
|
||||
use Intervention\Image\Drivers\AbstractDecoder;
|
||||
use Intervention\Image\Exceptions\DecoderException;
|
||||
use Intervention\Image\Interfaces\ColorInterface;
|
||||
use Intervention\Image\Interfaces\DecoderInterface;
|
||||
use Intervention\Image\Interfaces\ImageInterface;
|
||||
|
||||
class StringColorDecoder extends AbstractDecoder implements DecoderInterface
|
||||
{
|
||||
/**
|
||||
* Decode hsl color strings
|
||||
*/
|
||||
public function decode(mixed $input): ImageInterface|ColorInterface
|
||||
{
|
||||
if (!is_string($input)) {
|
||||
throw new DecoderException('Unable to decode input');
|
||||
}
|
||||
|
||||
$pattern = '/^hsl\((?P<h>[0-9\.]+), ?(?P<s>[0-9\.]+%?), ?(?P<l>[0-9\.]+%?)\)$/i';
|
||||
if (preg_match($pattern, $input, $matches) != 1) {
|
||||
throw new DecoderException('Unable to decode input');
|
||||
}
|
||||
|
||||
$values = array_map(function (string $value): int {
|
||||
return match (strpos($value, '%')) {
|
||||
false => intval(trim($value)),
|
||||
default => intval(trim(str_replace('%', '', $value))),
|
||||
};
|
||||
}, [$matches['h'], $matches['s'], $matches['l']]);
|
||||
|
||||
return new Color(...$values);
|
||||
}
|
||||
}
|
||||
30
upLoadImage/vendor/intervention/image/src/Colors/Hsv/Channels/Hue.php
vendored
Normal file
30
upLoadImage/vendor/intervention/image/src/Colors/Hsv/Channels/Hue.php
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Colors\Hsv\Channels;
|
||||
|
||||
use Intervention\Image\Colors\AbstractColorChannel;
|
||||
|
||||
class Hue extends AbstractColorChannel
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see ColorChannelInterface::min()
|
||||
*/
|
||||
public function min(): int
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see ColorChannelInterface::max()
|
||||
*/
|
||||
public function max(): int
|
||||
{
|
||||
return 360;
|
||||
}
|
||||
}
|
||||
30
upLoadImage/vendor/intervention/image/src/Colors/Hsv/Channels/Saturation.php
vendored
Normal file
30
upLoadImage/vendor/intervention/image/src/Colors/Hsv/Channels/Saturation.php
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Colors\Hsv\Channels;
|
||||
|
||||
use Intervention\Image\Colors\AbstractColorChannel;
|
||||
|
||||
class Saturation extends AbstractColorChannel
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see ColorChannelInterface::min()
|
||||
*/
|
||||
public function min(): int
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see ColorChannelInterface::max()
|
||||
*/
|
||||
public function max(): int
|
||||
{
|
||||
return 100;
|
||||
}
|
||||
}
|
||||
30
upLoadImage/vendor/intervention/image/src/Colors/Hsv/Channels/Value.php
vendored
Normal file
30
upLoadImage/vendor/intervention/image/src/Colors/Hsv/Channels/Value.php
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Colors\Hsv\Channels;
|
||||
|
||||
use Intervention\Image\Colors\AbstractColorChannel;
|
||||
|
||||
class Value extends AbstractColorChannel
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see ColorChannelInterface::min()
|
||||
*/
|
||||
public function min(): int
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see ColorChannelInterface::max()
|
||||
*/
|
||||
public function max(): int
|
||||
{
|
||||
return 100;
|
||||
}
|
||||
}
|
||||
132
upLoadImage/vendor/intervention/image/src/Colors/Hsv/Color.php
vendored
Normal file
132
upLoadImage/vendor/intervention/image/src/Colors/Hsv/Color.php
vendored
Normal file
@@ -0,0 +1,132 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Colors\Hsv;
|
||||
|
||||
use Intervention\Image\Colors\AbstractColor;
|
||||
use Intervention\Image\Colors\Hsv\Channels\Hue;
|
||||
use Intervention\Image\Colors\Hsv\Channels\Saturation;
|
||||
use Intervention\Image\Colors\Hsv\Channels\Value;
|
||||
use Intervention\Image\Colors\Rgb\Colorspace as RgbColorspace;
|
||||
use Intervention\Image\InputHandler;
|
||||
use Intervention\Image\Interfaces\ColorChannelInterface;
|
||||
use Intervention\Image\Interfaces\ColorInterface;
|
||||
use Intervention\Image\Interfaces\ColorspaceInterface;
|
||||
|
||||
class Color extends AbstractColor
|
||||
{
|
||||
/**
|
||||
* Create new color object
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(int $h, int $s, int $v)
|
||||
{
|
||||
/** @throws void */
|
||||
$this->channels = [
|
||||
new Hue($h),
|
||||
new Saturation($s),
|
||||
new Value($v),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see ColorInterface::colorspace()
|
||||
*/
|
||||
public function colorspace(): ColorspaceInterface
|
||||
{
|
||||
return new Colorspace();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see ColorInterface::create()
|
||||
*/
|
||||
public static function create(mixed $input): ColorInterface
|
||||
{
|
||||
return InputHandler::withDecoders([
|
||||
Decoders\StringColorDecoder::class,
|
||||
])->handle($input);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the Hue channel
|
||||
*/
|
||||
public function hue(): ColorChannelInterface
|
||||
{
|
||||
/** @throws void */
|
||||
return $this->channel(Hue::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the Saturation channel
|
||||
*/
|
||||
public function saturation(): ColorChannelInterface
|
||||
{
|
||||
/** @throws void */
|
||||
return $this->channel(Saturation::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the Value channel
|
||||
*/
|
||||
public function value(): ColorChannelInterface
|
||||
{
|
||||
/** @throws void */
|
||||
return $this->channel(Value::class);
|
||||
}
|
||||
|
||||
public function toHex(string $prefix = ''): string
|
||||
{
|
||||
return $this->convertTo(RgbColorspace::class)->toHex($prefix);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see ColorInterface::toString()
|
||||
*/
|
||||
public function toString(): string
|
||||
{
|
||||
return sprintf(
|
||||
'hsv(%d, %d%%, %d%%)',
|
||||
$this->hue()->value(),
|
||||
$this->saturation()->value(),
|
||||
$this->value()->value()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see ColorInterface::isGreyscale()
|
||||
*/
|
||||
public function isGreyscale(): bool
|
||||
{
|
||||
return $this->saturation()->value() == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see ColorInterface::isTransparent()
|
||||
*/
|
||||
public function isTransparent(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see ColorInterface::isClear()
|
||||
*/
|
||||
public function isClear(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
122
upLoadImage/vendor/intervention/image/src/Colors/Hsv/Colorspace.php
vendored
Normal file
122
upLoadImage/vendor/intervention/image/src/Colors/Hsv/Colorspace.php
vendored
Normal file
@@ -0,0 +1,122 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Colors\Hsv;
|
||||
|
||||
use Intervention\Image\Colors\Cmyk\Color as CmykColor;
|
||||
use Intervention\Image\Colors\Rgb\Color as RgbColor;
|
||||
use Intervention\Image\Colors\Hsl\Color as HslColor;
|
||||
use Intervention\Image\Colors\Rgb\Colorspace as RgbColorspace;
|
||||
use Intervention\Image\Exceptions\ColorException;
|
||||
use Intervention\Image\Interfaces\ColorChannelInterface;
|
||||
use Intervention\Image\Interfaces\ColorInterface;
|
||||
use Intervention\Image\Interfaces\ColorspaceInterface;
|
||||
|
||||
class Colorspace implements ColorspaceInterface
|
||||
{
|
||||
/**
|
||||
* Channel class names of colorspace
|
||||
*
|
||||
* @var array<string>
|
||||
*/
|
||||
public static array $channels = [
|
||||
Channels\Hue::class,
|
||||
Channels\Saturation::class,
|
||||
Channels\Value::class
|
||||
];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see ColorspaceInterface::colorFromNormalized()
|
||||
*/
|
||||
public function colorFromNormalized(array $normalized): ColorInterface
|
||||
{
|
||||
return new Color(...array_map(
|
||||
fn(string $classname, float $value_normalized) => (new $classname(normalized: $value_normalized))->value(),
|
||||
self::$channels,
|
||||
$normalized
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ColorException
|
||||
*/
|
||||
public function importColor(ColorInterface $color): ColorInterface
|
||||
{
|
||||
return match ($color::class) {
|
||||
CmykColor::class => $this->importRgbColor($color->convertTo(RgbColorspace::class)),
|
||||
RgbColor::class => $this->importRgbColor($color),
|
||||
HslColor::class => $this->importHslColor($color),
|
||||
default => $color,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ColorException
|
||||
*/
|
||||
protected function importRgbColor(ColorInterface $color): ColorInterface
|
||||
{
|
||||
if (!($color instanceof RgbColor)) {
|
||||
throw new ColorException('Unabled to import color of type ' . $color::class . '.');
|
||||
}
|
||||
|
||||
// normalized values of rgb channels
|
||||
$values = array_map(fn(ColorChannelInterface $channel): float => $channel->normalize(), $color->channels());
|
||||
|
||||
// take only RGB
|
||||
$values = array_slice($values, 0, 3);
|
||||
|
||||
// calculate chroma
|
||||
$min = min(...$values);
|
||||
$max = max(...$values);
|
||||
$chroma = $max - $min;
|
||||
|
||||
// calculate value
|
||||
$v = 100 * $max;
|
||||
|
||||
if ($chroma == 0) {
|
||||
// greyscale color
|
||||
return new Color(0, 0, intval(round($v)));
|
||||
}
|
||||
|
||||
// calculate saturation
|
||||
$s = 100 * ($chroma / $max);
|
||||
|
||||
// calculate hue
|
||||
[$r, $g, $b] = $values;
|
||||
$h = match (true) {
|
||||
($r == $min) => 3 - (($g - $b) / $chroma),
|
||||
($b == $min) => 1 - (($r - $g) / $chroma),
|
||||
default => 5 - (($b - $r) / $chroma),
|
||||
} * 60;
|
||||
|
||||
return new Color(
|
||||
intval(round($h)),
|
||||
intval(round($s)),
|
||||
intval(round($v))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ColorException
|
||||
*/
|
||||
protected function importHslColor(ColorInterface $color): ColorInterface
|
||||
{
|
||||
if (!($color instanceof HslColor)) {
|
||||
throw new ColorException('Unabled to import color of type ' . $color::class . '.');
|
||||
}
|
||||
|
||||
// normalized values of hsl channels
|
||||
[$h, $s, $l] = array_map(
|
||||
fn(ColorChannelInterface $channel): float => $channel->normalize(),
|
||||
$color->channels()
|
||||
);
|
||||
|
||||
$v = $l + $s * min($l, 1 - $l);
|
||||
$s = ($v == 0) ? 0 : 2 * (1 - $l / $v);
|
||||
|
||||
return $this->colorFromNormalized([$h, $s, $v]);
|
||||
}
|
||||
}
|
||||
39
upLoadImage/vendor/intervention/image/src/Colors/Hsv/Decoders/StringColorDecoder.php
vendored
Normal file
39
upLoadImage/vendor/intervention/image/src/Colors/Hsv/Decoders/StringColorDecoder.php
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Colors\Hsv\Decoders;
|
||||
|
||||
use Intervention\Image\Colors\Hsv\Color;
|
||||
use Intervention\Image\Drivers\AbstractDecoder;
|
||||
use Intervention\Image\Exceptions\DecoderException;
|
||||
use Intervention\Image\Interfaces\ColorInterface;
|
||||
use Intervention\Image\Interfaces\DecoderInterface;
|
||||
use Intervention\Image\Interfaces\ImageInterface;
|
||||
|
||||
class StringColorDecoder extends AbstractDecoder implements DecoderInterface
|
||||
{
|
||||
/**
|
||||
* Decode hsv/hsb color strings
|
||||
*/
|
||||
public function decode(mixed $input): ImageInterface|ColorInterface
|
||||
{
|
||||
if (!is_string($input)) {
|
||||
throw new DecoderException('Unable to decode input');
|
||||
}
|
||||
|
||||
$pattern = '/^hs(v|b)\((?P<h>[0-9\.]+), ?(?P<s>[0-9\.]+%?), ?(?P<v>[0-9\.]+%?)\)$/i';
|
||||
if (preg_match($pattern, $input, $matches) != 1) {
|
||||
throw new DecoderException('Unable to decode input');
|
||||
}
|
||||
|
||||
$values = array_map(function (string $value): int {
|
||||
return match (strpos($value, '%')) {
|
||||
false => intval(trim($value)),
|
||||
default => intval(trim(str_replace('%', '', $value))),
|
||||
};
|
||||
}, [$matches['h'], $matches['s'], $matches['v']]);
|
||||
|
||||
return new Color(...$values);
|
||||
}
|
||||
}
|
||||
22
upLoadImage/vendor/intervention/image/src/Colors/Profile.php
vendored
Normal file
22
upLoadImage/vendor/intervention/image/src/Colors/Profile.php
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Colors;
|
||||
|
||||
use Intervention\Image\File;
|
||||
use Intervention\Image\Exceptions\RuntimeException;
|
||||
use Intervention\Image\Interfaces\ProfileInterface;
|
||||
|
||||
class Profile extends File implements ProfileInterface
|
||||
{
|
||||
/**
|
||||
* Create profile object from path in file system
|
||||
*
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public static function fromPath(string $path): self
|
||||
{
|
||||
return new self(fopen($path, 'r'));
|
||||
}
|
||||
}
|
||||
18
upLoadImage/vendor/intervention/image/src/Colors/Rgb/Channels/Alpha.php
vendored
Normal file
18
upLoadImage/vendor/intervention/image/src/Colors/Rgb/Channels/Alpha.php
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Colors\Rgb\Channels;
|
||||
|
||||
class Alpha extends Red
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see ColorChannelInterface::toString()
|
||||
*/
|
||||
public function toString(): string
|
||||
{
|
||||
return strval(round($this->normalize(), 6));
|
||||
}
|
||||
}
|
||||
10
upLoadImage/vendor/intervention/image/src/Colors/Rgb/Channels/Blue.php
vendored
Normal file
10
upLoadImage/vendor/intervention/image/src/Colors/Rgb/Channels/Blue.php
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Colors\Rgb\Channels;
|
||||
|
||||
class Blue extends Red
|
||||
{
|
||||
//
|
||||
}
|
||||
10
upLoadImage/vendor/intervention/image/src/Colors/Rgb/Channels/Green.php
vendored
Normal file
10
upLoadImage/vendor/intervention/image/src/Colors/Rgb/Channels/Green.php
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Colors\Rgb\Channels;
|
||||
|
||||
class Green extends Red
|
||||
{
|
||||
//
|
||||
}
|
||||
30
upLoadImage/vendor/intervention/image/src/Colors/Rgb/Channels/Red.php
vendored
Normal file
30
upLoadImage/vendor/intervention/image/src/Colors/Rgb/Channels/Red.php
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Colors\Rgb\Channels;
|
||||
|
||||
use Intervention\Image\Colors\AbstractColorChannel;
|
||||
|
||||
class Red extends AbstractColorChannel
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see ColorChannelInterface::min()
|
||||
*/
|
||||
public function min(): int
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see ColorChannelInterface::max()
|
||||
*/
|
||||
public function max(): int
|
||||
{
|
||||
return 255;
|
||||
}
|
||||
}
|
||||
179
upLoadImage/vendor/intervention/image/src/Colors/Rgb/Color.php
vendored
Normal file
179
upLoadImage/vendor/intervention/image/src/Colors/Rgb/Color.php
vendored
Normal file
@@ -0,0 +1,179 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Colors\Rgb;
|
||||
|
||||
use Intervention\Image\Colors\AbstractColor;
|
||||
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\Channels\Alpha;
|
||||
use Intervention\Image\InputHandler;
|
||||
use Intervention\Image\Interfaces\ColorChannelInterface;
|
||||
use Intervention\Image\Interfaces\ColorInterface;
|
||||
use Intervention\Image\Interfaces\ColorspaceInterface;
|
||||
|
||||
class Color extends AbstractColor
|
||||
{
|
||||
/**
|
||||
* Create new instance
|
||||
*
|
||||
* @return ColorInterface
|
||||
*/
|
||||
public function __construct(int $r, int $g, int $b, int $a = 255)
|
||||
{
|
||||
/** @throws void */
|
||||
$this->channels = [
|
||||
new Red($r),
|
||||
new Green($g),
|
||||
new Blue($b),
|
||||
new Alpha($a),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see ColorInterface::colorspace()
|
||||
*/
|
||||
public function colorspace(): ColorspaceInterface
|
||||
{
|
||||
return new Colorspace();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see ColorInterface::create()
|
||||
*/
|
||||
public static function create(mixed $input): ColorInterface
|
||||
{
|
||||
return InputHandler::withDecoders([
|
||||
Decoders\HexColorDecoder::class,
|
||||
Decoders\StringColorDecoder::class,
|
||||
Decoders\TransparentColorDecoder::class,
|
||||
Decoders\HtmlColornameDecoder::class,
|
||||
])->handle($input);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the RGB red color channel
|
||||
*/
|
||||
public function red(): ColorChannelInterface
|
||||
{
|
||||
/** @throws void */
|
||||
return $this->channel(Red::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the RGB green color channel
|
||||
*/
|
||||
public function green(): ColorChannelInterface
|
||||
{
|
||||
/** @throws void */
|
||||
return $this->channel(Green::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the RGB blue color channel
|
||||
*/
|
||||
public function blue(): ColorChannelInterface
|
||||
{
|
||||
/** @throws void */
|
||||
return $this->channel(Blue::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the colors alpha channel
|
||||
*/
|
||||
public function alpha(): ColorChannelInterface
|
||||
{
|
||||
/** @throws void */
|
||||
return $this->channel(Alpha::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see ColorInterface::toHex()
|
||||
*/
|
||||
public function toHex(string $prefix = ''): string
|
||||
{
|
||||
if ($this->isTransparent()) {
|
||||
return sprintf(
|
||||
'%s%02x%02x%02x%02x',
|
||||
$prefix,
|
||||
$this->red()->value(),
|
||||
$this->green()->value(),
|
||||
$this->blue()->value(),
|
||||
$this->alpha()->value()
|
||||
);
|
||||
}
|
||||
|
||||
return sprintf(
|
||||
'%s%02x%02x%02x',
|
||||
$prefix,
|
||||
$this->red()->value(),
|
||||
$this->green()->value(),
|
||||
$this->blue()->value()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see ColorInterface::toString()
|
||||
*/
|
||||
public function toString(): string
|
||||
{
|
||||
if ($this->isTransparent()) {
|
||||
return sprintf(
|
||||
'rgba(%d, %d, %d, %.1F)',
|
||||
$this->red()->value(),
|
||||
$this->green()->value(),
|
||||
$this->blue()->value(),
|
||||
$this->alpha()->normalize(),
|
||||
);
|
||||
}
|
||||
|
||||
return sprintf(
|
||||
'rgb(%d, %d, %d)',
|
||||
$this->red()->value(),
|
||||
$this->green()->value(),
|
||||
$this->blue()->value()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see ColorInterface::isGreyscale()
|
||||
*/
|
||||
public function isGreyscale(): bool
|
||||
{
|
||||
$values = [$this->red()->value(), $this->green()->value(), $this->blue()->value()];
|
||||
|
||||
return count(array_unique($values, SORT_REGULAR)) === 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see ColorInterface::isTransparent()
|
||||
*/
|
||||
public function isTransparent(): bool
|
||||
{
|
||||
return $this->alpha()->value() < $this->alpha()->max();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see ColorInterface::isClear()
|
||||
*/
|
||||
public function isClear(): bool
|
||||
{
|
||||
return $this->alpha()->value() == 0;
|
||||
}
|
||||
}
|
||||
135
upLoadImage/vendor/intervention/image/src/Colors/Rgb/Colorspace.php
vendored
Normal file
135
upLoadImage/vendor/intervention/image/src/Colors/Rgb/Colorspace.php
vendored
Normal file
@@ -0,0 +1,135 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Colors\Rgb;
|
||||
|
||||
use Intervention\Image\Colors\Hsv\Color as HsvColor;
|
||||
use Intervention\Image\Colors\Hsl\Color as HslColor;
|
||||
use Intervention\Image\Colors\Cmyk\Color as CmykColor;
|
||||
use Intervention\Image\Exceptions\ColorException;
|
||||
use Intervention\Image\Interfaces\ColorChannelInterface;
|
||||
use Intervention\Image\Interfaces\ColorInterface;
|
||||
use Intervention\Image\Interfaces\ColorspaceInterface;
|
||||
|
||||
class Colorspace implements ColorspaceInterface
|
||||
{
|
||||
/**
|
||||
* Channel class names of colorspace
|
||||
*
|
||||
* @var array<string>
|
||||
*/
|
||||
public static array $channels = [
|
||||
Channels\Red::class,
|
||||
Channels\Green::class,
|
||||
Channels\Blue::class,
|
||||
Channels\Alpha::class
|
||||
];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see ColorspaceInterface::colorFromNormalized()
|
||||
*/
|
||||
public function colorFromNormalized(array $normalized): ColorInterface
|
||||
{
|
||||
return new Color(...array_map(
|
||||
fn($classname, float $value_normalized) => (new $classname(normalized: $value_normalized))->value(),
|
||||
self::$channels,
|
||||
$normalized,
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ColorException
|
||||
*/
|
||||
public function importColor(ColorInterface $color): ColorInterface
|
||||
{
|
||||
return match ($color::class) {
|
||||
CmykColor::class => $this->importCmykColor($color),
|
||||
HsvColor::class => $this->importHsvColor($color),
|
||||
HslColor::class => $this->importHslColor($color),
|
||||
default => $color,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ColorException
|
||||
*/
|
||||
protected function importCmykColor(ColorInterface $color): ColorInterface
|
||||
{
|
||||
if (!($color instanceof CmykColor)) {
|
||||
throw new ColorException('Unabled to import color of type ' . $color::class . '.');
|
||||
}
|
||||
|
||||
return new Color(
|
||||
(int) (255 * (1 - $color->cyan()->normalize()) * (1 - $color->key()->normalize())),
|
||||
(int) (255 * (1 - $color->magenta()->normalize()) * (1 - $color->key()->normalize())),
|
||||
(int) (255 * (1 - $color->yellow()->normalize()) * (1 - $color->key()->normalize())),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ColorException
|
||||
*/
|
||||
protected function importHsvColor(ColorInterface $color): ColorInterface
|
||||
{
|
||||
if (!($color instanceof HsvColor)) {
|
||||
throw new ColorException('Unabled to import color of type ' . $color::class . '.');
|
||||
}
|
||||
|
||||
$chroma = $color->value()->normalize() * $color->saturation()->normalize();
|
||||
$hue = $color->hue()->normalize() * 6;
|
||||
$x = $chroma * (1 - abs(fmod($hue, 2) - 1));
|
||||
|
||||
// connect channel values
|
||||
$values = match (true) {
|
||||
$hue < 1 => [$chroma, $x, 0],
|
||||
$hue < 2 => [$x, $chroma, 0],
|
||||
$hue < 3 => [0, $chroma, $x],
|
||||
$hue < 4 => [0, $x, $chroma],
|
||||
$hue < 5 => [$x, 0, $chroma],
|
||||
default => [$chroma, 0, $x],
|
||||
};
|
||||
|
||||
// add to each value
|
||||
$values = array_map(fn(float|int $value): float => $value + $color->value()->normalize() - $chroma, $values);
|
||||
$values[] = 1; // append alpha channel value
|
||||
|
||||
return $this->colorFromNormalized($values);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ColorException
|
||||
*/
|
||||
protected function importHslColor(ColorInterface $color): ColorInterface
|
||||
{
|
||||
if (!($color instanceof HslColor)) {
|
||||
throw new ColorException('Unabled to import color of type ' . $color::class . '.');
|
||||
}
|
||||
|
||||
// normalized values of hsl channels
|
||||
[$h, $s, $l] = array_map(
|
||||
fn(ColorChannelInterface $channel): float => $channel->normalize(),
|
||||
$color->channels()
|
||||
);
|
||||
|
||||
$c = (1 - abs(2 * $l - 1)) * $s;
|
||||
$x = $c * (1 - abs(fmod($h * 6, 2) - 1));
|
||||
$m = $l - $c / 2;
|
||||
|
||||
$values = match (true) {
|
||||
$h < 1 / 6 => [$c, $x, 0],
|
||||
$h < 2 / 6 => [$x, $c, 0],
|
||||
$h < 3 / 6 => [0, $c, $x],
|
||||
$h < 4 / 6 => [0, $x, $c],
|
||||
$h < 5 / 6 => [$x, 0, $c],
|
||||
default => [$c, 0, $x],
|
||||
};
|
||||
|
||||
$values = array_map(fn(float|int $value): float => $value + $m, $values);
|
||||
$values[] = 1; // append alpha channel value
|
||||
|
||||
return $this->colorFromNormalized($values);
|
||||
}
|
||||
}
|
||||
46
upLoadImage/vendor/intervention/image/src/Colors/Rgb/Decoders/HexColorDecoder.php
vendored
Normal file
46
upLoadImage/vendor/intervention/image/src/Colors/Rgb/Decoders/HexColorDecoder.php
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Colors\Rgb\Decoders;
|
||||
|
||||
use Intervention\Image\Colors\Rgb\Color;
|
||||
use Intervention\Image\Drivers\AbstractDecoder;
|
||||
use Intervention\Image\Exceptions\DecoderException;
|
||||
use Intervention\Image\Interfaces\ColorInterface;
|
||||
use Intervention\Image\Interfaces\DecoderInterface;
|
||||
use Intervention\Image\Interfaces\ImageInterface;
|
||||
|
||||
class HexColorDecoder extends AbstractDecoder implements DecoderInterface
|
||||
{
|
||||
/**
|
||||
* Decode hexadecimal rgb colors with and without transparency
|
||||
*/
|
||||
public function decode(mixed $input): ImageInterface|ColorInterface
|
||||
{
|
||||
if (!is_string($input)) {
|
||||
throw new DecoderException('Unable to decode input');
|
||||
}
|
||||
|
||||
$pattern = '/^#?(?P<hex>[a-f\d]{3}(?:[a-f\d]?|(?:[a-f\d]{3}(?:[a-f\d]{2})?)?)\b)$/i';
|
||||
if (preg_match($pattern, $input, $matches) != 1) {
|
||||
throw new DecoderException('Unable to decode input');
|
||||
}
|
||||
|
||||
$values = match (strlen($matches['hex'])) {
|
||||
3, 4 => str_split($matches['hex']),
|
||||
6, 8 => str_split($matches['hex'], 2),
|
||||
default => throw new DecoderException('Unable to decode input'),
|
||||
};
|
||||
|
||||
$values = array_map(function (string $value): float|int {
|
||||
return match (strlen($value)) {
|
||||
1 => hexdec($value . $value),
|
||||
2 => hexdec($value),
|
||||
default => throw new DecoderException('Unable to decode input'),
|
||||
};
|
||||
}, $values);
|
||||
|
||||
return new Color(...$values);
|
||||
}
|
||||
}
|
||||
176
upLoadImage/vendor/intervention/image/src/Colors/Rgb/Decoders/HtmlColornameDecoder.php
vendored
Normal file
176
upLoadImage/vendor/intervention/image/src/Colors/Rgb/Decoders/HtmlColornameDecoder.php
vendored
Normal file
@@ -0,0 +1,176 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Colors\Rgb\Decoders;
|
||||
|
||||
use Intervention\Image\Exceptions\DecoderException;
|
||||
use Intervention\Image\Interfaces\ColorInterface;
|
||||
use Intervention\Image\Interfaces\DecoderInterface;
|
||||
use Intervention\Image\Interfaces\ImageInterface;
|
||||
|
||||
class HtmlColornameDecoder extends HexColorDecoder implements DecoderInterface
|
||||
{
|
||||
/**
|
||||
* Available color names and their corresponding hex codes
|
||||
*
|
||||
* @var array<string, string>
|
||||
*/
|
||||
protected static array $names = [
|
||||
'lightsalmon' => '#ffa07a',
|
||||
'salmon' => '#fa8072',
|
||||
'darksalmon' => '#e9967a',
|
||||
'lightcoral' => '#f08080',
|
||||
'indianred' => '#cd5c5c',
|
||||
'crimson' => '#dc143c',
|
||||
'firebrick' => '#b22222',
|
||||
'red' => '#ff0000',
|
||||
'darkred' => '#8b0000',
|
||||
'coral' => '#ff7f50',
|
||||
'tomato' => '#ff6347',
|
||||
'orangered' => '#ff4500',
|
||||
'gold' => '#ffd700',
|
||||
'orange' => '#ffa500',
|
||||
'darkorange' => '#ff8c00',
|
||||
'lightyellow' => '#ffffe0',
|
||||
'lemonchiffon' => '#fffacd',
|
||||
'lightgoldenrodyellow' => '#fafad2',
|
||||
'papayawhip' => '#ffefd5',
|
||||
'moccasin' => '#ffe4b5',
|
||||
'peachpuff' => '#ffdab9',
|
||||
'palegoldenrod' => '#eee8aa',
|
||||
'khaki' => '#f0e68c',
|
||||
'darkkhaki' => '#bdb76b',
|
||||
'yellow' => '#ffff00',
|
||||
'lawngreen' => '#7cfc00',
|
||||
'chartreuse' => '#7fff00',
|
||||
'limegreen' => '#32cd32',
|
||||
'lime' => '#00ff00',
|
||||
'forestgreen' => '#228b22',
|
||||
'green' => '#008000',
|
||||
'darkgreen' => '#006400',
|
||||
'greenyellow' => '#adff2f',
|
||||
'yellowgreen' => '#9acd32',
|
||||
'springgreen' => '#00ff7f',
|
||||
'mediumspringgreen' => '#00fa9a',
|
||||
'lightgreen' => '#90ee90',
|
||||
'palegreen' => '#98fb98',
|
||||
'darkseagreen' => '#8fbc8f',
|
||||
'mediumseagre' => 'en #3cb371',
|
||||
'seagreen' => '#2e8b57',
|
||||
'olive' => '#808000',
|
||||
'darkolivegreen' => '#556b2f',
|
||||
'olivedrab' => '#6b8e23',
|
||||
'lightcyan' => '#e0ffff',
|
||||
'cyan' => '#00ffff',
|
||||
'aqua' => '#00ffff',
|
||||
'aquamarine' => '#7fffd4',
|
||||
'mediumaquamarine' => '#66cdaa',
|
||||
'paleturquoise' => '#afeeee',
|
||||
'turquoise' => '#40e0d0',
|
||||
'mediumturquoise' => '#48d1cc',
|
||||
'darkturquoise' => '#00ced1',
|
||||
'lightseagreen' => '#20b2aa',
|
||||
'cadetblue' => '#5f9ea0',
|
||||
'darkcyan' => '#008b8b',
|
||||
'teal' => '#008080',
|
||||
'powderblue' => '#b0e0e6',
|
||||
'lightblue' => '#add8e6',
|
||||
'lightskyblue' => '#87cefa',
|
||||
'skyblue' => '#87ceeb',
|
||||
'deepskyblue' => '#00bfff',
|
||||
'lightsteelblue' => '#b0c4de',
|
||||
'dodgerblue' => '#1e90ff',
|
||||
'cornflowerblue' => '#6495ed',
|
||||
'steelblue' => '#4682b4',
|
||||
'royalblue' => '#4169e1',
|
||||
'blue' => '#0000ff',
|
||||
'mediumblue' => '#0000cd',
|
||||
'darkblue' => '#00008b',
|
||||
'navy' => '#000080',
|
||||
'midnightblue' => '#191970',
|
||||
'mediumslateblue' => '#7b68ee',
|
||||
'slateblue' => '#6a5acd',
|
||||
'darkslateblue' => '#483d8b',
|
||||
'lavender' => '#e6e6fa',
|
||||
'thistle' => '#d8bfd8',
|
||||
'plum' => '#dda0dd',
|
||||
'violet' => '#ee82ee',
|
||||
'orchid' => '#da70d6',
|
||||
'fuchsia' => '#ff00ff',
|
||||
'magenta' => '#ff00ff',
|
||||
'mediumorchid' => '#ba55d3',
|
||||
'mediumpurple' => '#9370db',
|
||||
'blueviolet' => '#8a2be2',
|
||||
'darkviolet' => '#9400d3',
|
||||
'darkorchid' => '#9932cc',
|
||||
'darkmagenta' => '#8b008b',
|
||||
'purple' => '#800080',
|
||||
'indigo' => '#4b0082',
|
||||
'pink' => '#ffc0cb',
|
||||
'lightpink' => '#ffb6c1',
|
||||
'hotpink' => '#ff69b4',
|
||||
'deeppink' => '#ff1493',
|
||||
'palevioletred' => '#db7093',
|
||||
'mediumvioletred' => '#c71585',
|
||||
'white' => '#ffffff',
|
||||
'snow' => '#fffafa',
|
||||
'honeydew' => '#f0fff0',
|
||||
'mintcream' => '#f5fffa',
|
||||
'azure' => '#f0ffff',
|
||||
'aliceblue' => '#f0f8ff',
|
||||
'ghostwhite' => '#f8f8ff',
|
||||
'whitesmoke' => '#f5f5f5',
|
||||
'seashell' => '#fff5ee',
|
||||
'beige' => '#f5f5dc',
|
||||
'oldlace' => '#fdf5e6',
|
||||
'floralwhite' => '#fffaf0',
|
||||
'ivory' => '#fffff0',
|
||||
'antiquewhite' => '#faebd7',
|
||||
'linen' => '#faf0e6',
|
||||
'lavenderblush' => '#fff0f5',
|
||||
'mistyrose' => '#ffe4e1',
|
||||
'gainsboro' => '#dcdcdc',
|
||||
'lightgray' => '#d3d3d3',
|
||||
'silver' => '#c0c0c0',
|
||||
'darkgray' => '#a9a9a9',
|
||||
'gray' => '#808080',
|
||||
'dimgray' => '#696969',
|
||||
'lightslategray' => '#778899',
|
||||
'slategray' => '#708090',
|
||||
'darkslategray' => '#2f4f4f',
|
||||
'black' => '#000000',
|
||||
'cornsilk' => '#fff8dc',
|
||||
'blanchedalmond' => '#ffebcd',
|
||||
'bisque' => '#ffe4c4',
|
||||
'navajowhite' => '#ffdead',
|
||||
'wheat' => '#f5deb3',
|
||||
'burlywood' => '#deb887',
|
||||
'tan' => '#d2b48c',
|
||||
'rosybrown' => '#bc8f8f',
|
||||
'sandybrown' => '#f4a460',
|
||||
'goldenrod' => '#daa520',
|
||||
'peru' => '#cd853f',
|
||||
'chocolate' => '#d2691e',
|
||||
'saddlebrown' => '#8b4513',
|
||||
'sienna' => '#a0522d',
|
||||
'brown' => '#a52a2a',
|
||||
'maroon' => '#800000',
|
||||
];
|
||||
|
||||
/**
|
||||
* Decode html color names
|
||||
*/
|
||||
public function decode(mixed $input): ImageInterface|ColorInterface
|
||||
{
|
||||
if (!is_string($input)) {
|
||||
throw new DecoderException('Unable to decode input');
|
||||
}
|
||||
|
||||
if (!array_key_exists(strtolower($input), static::$names)) {
|
||||
throw new DecoderException('Unable to decode input');
|
||||
}
|
||||
|
||||
return parent::decode(static::$names[strtolower($input)]);
|
||||
}
|
||||
}
|
||||
49
upLoadImage/vendor/intervention/image/src/Colors/Rgb/Decoders/StringColorDecoder.php
vendored
Normal file
49
upLoadImage/vendor/intervention/image/src/Colors/Rgb/Decoders/StringColorDecoder.php
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Colors\Rgb\Decoders;
|
||||
|
||||
use Intervention\Image\Colors\Rgb\Color;
|
||||
use Intervention\Image\Drivers\AbstractDecoder;
|
||||
use Intervention\Image\Exceptions\DecoderException;
|
||||
use Intervention\Image\Interfaces\ColorInterface;
|
||||
use Intervention\Image\Interfaces\DecoderInterface;
|
||||
use Intervention\Image\Interfaces\ImageInterface;
|
||||
|
||||
class StringColorDecoder extends AbstractDecoder implements DecoderInterface
|
||||
{
|
||||
/**
|
||||
* Decode rgb color strings
|
||||
*/
|
||||
public function decode(mixed $input): ImageInterface|ColorInterface
|
||||
{
|
||||
if (!is_string($input)) {
|
||||
throw new DecoderException('Unable to decode input');
|
||||
}
|
||||
|
||||
$pattern = '/^s?rgba?\((?P<r>[0-9\.]+%?), ?(?P<g>[0-9\.]+%?), ?(?P<b>[0-9\.]+%?)' .
|
||||
'(?:, ?(?P<a>(?:1)|(?:1\.0*)|(?:0)|(?:0?\.\d+%?)|(?:\d{1,3}%)))?\)$/i';
|
||||
if (preg_match($pattern, $input, $matches) != 1) {
|
||||
throw new DecoderException('Unable to decode input');
|
||||
}
|
||||
|
||||
// rgb values
|
||||
$values = array_map(function (string $value): int {
|
||||
return match (strpos($value, '%')) {
|
||||
false => intval(trim($value)),
|
||||
default => intval(round(floatval(trim(str_replace('%', '', $value))) / 100 * 255)),
|
||||
};
|
||||
}, [$matches['r'], $matches['g'], $matches['b']]);
|
||||
|
||||
// alpha value
|
||||
if (array_key_exists('a', $matches)) {
|
||||
$values[] = match (true) {
|
||||
strpos($matches['a'], '%') => round(intval(trim(str_replace('%', '', $matches['a']))) / 2.55),
|
||||
default => intval(round(floatval(trim($matches['a'])) * 255)),
|
||||
};
|
||||
}
|
||||
|
||||
return new Color(...$values);
|
||||
}
|
||||
}
|
||||
30
upLoadImage/vendor/intervention/image/src/Colors/Rgb/Decoders/TransparentColorDecoder.php
vendored
Normal file
30
upLoadImage/vendor/intervention/image/src/Colors/Rgb/Decoders/TransparentColorDecoder.php
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Colors\Rgb\Decoders;
|
||||
|
||||
use Intervention\Image\Exceptions\DecoderException;
|
||||
use Intervention\Image\Interfaces\ImageInterface;
|
||||
use Intervention\Image\Interfaces\ColorInterface;
|
||||
|
||||
class TransparentColorDecoder extends HexColorDecoder
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see DecoderInterface::decode()
|
||||
*/
|
||||
public function decode(mixed $input): ImageInterface|ColorInterface
|
||||
{
|
||||
if (!is_string($input)) {
|
||||
throw new DecoderException('Unable to decode input');
|
||||
}
|
||||
|
||||
if (strtolower($input) !== 'transparent') {
|
||||
throw new DecoderException('Unable to decode input');
|
||||
}
|
||||
|
||||
return parent::decode('#ffffff00');
|
||||
}
|
||||
}
|
||||
70
upLoadImage/vendor/intervention/image/src/Config.php
vendored
Normal file
70
upLoadImage/vendor/intervention/image/src/Config.php
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image;
|
||||
|
||||
use Intervention\Image\Exceptions\InputException;
|
||||
|
||||
class Config
|
||||
{
|
||||
/**
|
||||
* Create config object instance
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(
|
||||
public bool $autoOrientation = true,
|
||||
public bool $decodeAnimation = true,
|
||||
public mixed $blendingColor = 'ffffff',
|
||||
public bool $strip = false,
|
||||
) {
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Set values of given config options
|
||||
*
|
||||
* @throws InputException
|
||||
*/
|
||||
public function setOptions(mixed ...$options): self
|
||||
{
|
||||
foreach ($this->prepareOptions($options) as $name => $value) {
|
||||
if (!property_exists($this, $name)) {
|
||||
throw new InputException('Property ' . $name . ' does not exists for ' . $this::class . '.');
|
||||
}
|
||||
|
||||
$this->{$name} = $value;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method makes it possible to call self::setOptions() with a single
|
||||
* array instead of named parameters
|
||||
*
|
||||
* @param array<mixed> $options
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
private function prepareOptions(array $options): array
|
||||
{
|
||||
if ($options === []) {
|
||||
return $options;
|
||||
}
|
||||
|
||||
if (count($options) > 1) {
|
||||
return $options;
|
||||
}
|
||||
|
||||
if (!array_key_exists(0, $options)) {
|
||||
return $options;
|
||||
}
|
||||
|
||||
if (!is_array($options[0])) {
|
||||
return $options;
|
||||
}
|
||||
|
||||
return $options[0];
|
||||
}
|
||||
}
|
||||
12
upLoadImage/vendor/intervention/image/src/Decoders/Base64ImageDecoder.php
vendored
Normal file
12
upLoadImage/vendor/intervention/image/src/Decoders/Base64ImageDecoder.php
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Decoders;
|
||||
|
||||
use Intervention\Image\Drivers\SpecializableDecoder;
|
||||
|
||||
class Base64ImageDecoder extends SpecializableDecoder
|
||||
{
|
||||
//
|
||||
}
|
||||
12
upLoadImage/vendor/intervention/image/src/Decoders/BinaryImageDecoder.php
vendored
Normal file
12
upLoadImage/vendor/intervention/image/src/Decoders/BinaryImageDecoder.php
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Decoders;
|
||||
|
||||
use Intervention\Image\Drivers\SpecializableDecoder;
|
||||
|
||||
class BinaryImageDecoder extends SpecializableDecoder
|
||||
{
|
||||
//
|
||||
}
|
||||
27
upLoadImage/vendor/intervention/image/src/Decoders/ColorObjectDecoder.php
vendored
Normal file
27
upLoadImage/vendor/intervention/image/src/Decoders/ColorObjectDecoder.php
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Decoders;
|
||||
|
||||
use Intervention\Image\Drivers\AbstractDecoder;
|
||||
use Intervention\Image\Exceptions\DecoderException;
|
||||
use Intervention\Image\Interfaces\ColorInterface;
|
||||
use Intervention\Image\Interfaces\ImageInterface;
|
||||
|
||||
class ColorObjectDecoder extends AbstractDecoder
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see DecoderInterface::decode()
|
||||
*/
|
||||
public function decode(mixed $input): ImageInterface|ColorInterface
|
||||
{
|
||||
if (!is_a($input, ColorInterface::class)) {
|
||||
throw new DecoderException('Unable to decode input');
|
||||
}
|
||||
|
||||
return $input;
|
||||
}
|
||||
}
|
||||
12
upLoadImage/vendor/intervention/image/src/Decoders/DataUriImageDecoder.php
vendored
Normal file
12
upLoadImage/vendor/intervention/image/src/Decoders/DataUriImageDecoder.php
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Decoders;
|
||||
|
||||
use Intervention\Image\Drivers\SpecializableDecoder;
|
||||
|
||||
class DataUriImageDecoder extends SpecializableDecoder
|
||||
{
|
||||
//
|
||||
}
|
||||
12
upLoadImage/vendor/intervention/image/src/Decoders/EncodedImageObjectDecoder.php
vendored
Normal file
12
upLoadImage/vendor/intervention/image/src/Decoders/EncodedImageObjectDecoder.php
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Decoders;
|
||||
|
||||
use Intervention\Image\Drivers\SpecializableDecoder;
|
||||
|
||||
class EncodedImageObjectDecoder extends SpecializableDecoder
|
||||
{
|
||||
//
|
||||
}
|
||||
12
upLoadImage/vendor/intervention/image/src/Decoders/FilePathImageDecoder.php
vendored
Normal file
12
upLoadImage/vendor/intervention/image/src/Decoders/FilePathImageDecoder.php
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Decoders;
|
||||
|
||||
use Intervention\Image\Drivers\SpecializableDecoder;
|
||||
|
||||
class FilePathImageDecoder extends SpecializableDecoder
|
||||
{
|
||||
//
|
||||
}
|
||||
12
upLoadImage/vendor/intervention/image/src/Decoders/FilePointerImageDecoder.php
vendored
Normal file
12
upLoadImage/vendor/intervention/image/src/Decoders/FilePointerImageDecoder.php
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Decoders;
|
||||
|
||||
use Intervention\Image\Drivers\SpecializableDecoder;
|
||||
|
||||
class FilePointerImageDecoder extends SpecializableDecoder
|
||||
{
|
||||
//
|
||||
}
|
||||
27
upLoadImage/vendor/intervention/image/src/Decoders/ImageObjectDecoder.php
vendored
Normal file
27
upLoadImage/vendor/intervention/image/src/Decoders/ImageObjectDecoder.php
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Decoders;
|
||||
|
||||
use Intervention\Image\Drivers\AbstractDecoder;
|
||||
use Intervention\Image\Exceptions\DecoderException;
|
||||
use Intervention\Image\Interfaces\ImageInterface;
|
||||
use Intervention\Image\Interfaces\ColorInterface;
|
||||
|
||||
class ImageObjectDecoder extends AbstractDecoder
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see DecoderInterface::decode()
|
||||
*/
|
||||
public function decode(mixed $input): ImageInterface|ColorInterface
|
||||
{
|
||||
if (!is_a($input, ImageInterface::class)) {
|
||||
throw new DecoderException('Unable to decode input');
|
||||
}
|
||||
|
||||
return $input;
|
||||
}
|
||||
}
|
||||
12
upLoadImage/vendor/intervention/image/src/Decoders/NativeObjectDecoder.php
vendored
Normal file
12
upLoadImage/vendor/intervention/image/src/Decoders/NativeObjectDecoder.php
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Decoders;
|
||||
|
||||
use Intervention\Image\Drivers\SpecializableDecoder;
|
||||
|
||||
class NativeObjectDecoder extends SpecializableDecoder
|
||||
{
|
||||
//
|
||||
}
|
||||
12
upLoadImage/vendor/intervention/image/src/Decoders/SplFileInfoImageDecoder.php
vendored
Normal file
12
upLoadImage/vendor/intervention/image/src/Decoders/SplFileInfoImageDecoder.php
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Decoders;
|
||||
|
||||
use Intervention\Image\Drivers\SpecializableDecoder;
|
||||
|
||||
class SplFileInfoImageDecoder extends SpecializableDecoder
|
||||
{
|
||||
//
|
||||
}
|
||||
146
upLoadImage/vendor/intervention/image/src/Drivers/AbstractDecoder.php
vendored
Normal file
146
upLoadImage/vendor/intervention/image/src/Drivers/AbstractDecoder.php
vendored
Normal file
@@ -0,0 +1,146 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Drivers;
|
||||
|
||||
use Exception;
|
||||
use Intervention\Image\Collection;
|
||||
use Intervention\Image\Interfaces\CollectionInterface;
|
||||
use Intervention\Image\Interfaces\DecoderInterface;
|
||||
use Intervention\Image\Traits\CanBuildFilePointer;
|
||||
|
||||
abstract class AbstractDecoder implements DecoderInterface
|
||||
{
|
||||
use CanBuildFilePointer;
|
||||
|
||||
/**
|
||||
* Determine if the given input is GIF data format
|
||||
*/
|
||||
protected function isGifFormat(string $input): bool
|
||||
{
|
||||
return str_starts_with($input, 'GIF87a') || str_starts_with($input, 'GIF89a');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if given input is a path to an existing regular file
|
||||
*/
|
||||
protected function isFile(mixed $input): bool
|
||||
{
|
||||
if (!is_string($input)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (strlen($input) > PHP_MAXPATHLEN) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
if (!@is_file($input)) {
|
||||
return false;
|
||||
}
|
||||
} catch (Exception) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract and return EXIF data from given input which can be binary image
|
||||
* data or a file path.
|
||||
*
|
||||
* @return CollectionInterface<string, mixed>
|
||||
*/
|
||||
protected function extractExifData(string $path_or_data): CollectionInterface
|
||||
{
|
||||
if (!function_exists('exif_read_data')) {
|
||||
return new Collection();
|
||||
}
|
||||
|
||||
try {
|
||||
$source = match (true) {
|
||||
$this->isFile($path_or_data) => $path_or_data, // path
|
||||
default => $this->buildFilePointer($path_or_data), // data
|
||||
};
|
||||
|
||||
// extract exif data
|
||||
$data = @exif_read_data($source, null, true);
|
||||
if (is_resource($source)) {
|
||||
fclose($source);
|
||||
}
|
||||
} catch (Exception) {
|
||||
$data = [];
|
||||
}
|
||||
|
||||
return new Collection(is_array($data) ? $data : []);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if given input is base64 encoded data
|
||||
*/
|
||||
protected function isValidBase64(mixed $input): bool
|
||||
{
|
||||
if (!is_string($input)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return base64_encode(base64_decode($input)) === str_replace(["\n", "\r"], '', $input);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse data uri
|
||||
*/
|
||||
protected function parseDataUri(mixed $input): object
|
||||
{
|
||||
$pattern = "/^data:(?P<mediatype>\w+\/[-+.\w]+)?" .
|
||||
"(?P<parameters>(;[-\w]+=[-\w]+)*)(?P<base64>;base64)?,(?P<data>.*)/";
|
||||
|
||||
$result = preg_match($pattern, (string) $input, $matches);
|
||||
|
||||
return new class ($matches, $result)
|
||||
{
|
||||
/**
|
||||
* @param array<mixed> $matches
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(private array $matches, private int|false $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 isBase64Encoded(): bool
|
||||
{
|
||||
return isset($this->matches['base64']) && $this->matches['base64'] === ';base64';
|
||||
}
|
||||
|
||||
public function data(): ?string
|
||||
{
|
||||
if (isset($this->matches['data']) && !empty($this->matches['data'])) {
|
||||
return $this->matches['data'];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
127
upLoadImage/vendor/intervention/image/src/Drivers/AbstractDriver.php
vendored
Normal file
127
upLoadImage/vendor/intervention/image/src/Drivers/AbstractDriver.php
vendored
Normal file
@@ -0,0 +1,127 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Drivers;
|
||||
|
||||
use Intervention\Image\Config;
|
||||
use Intervention\Image\Exceptions\DriverException;
|
||||
use Intervention\Image\Exceptions\NotSupportedException;
|
||||
use Intervention\Image\InputHandler;
|
||||
use Intervention\Image\Interfaces\AnalyzerInterface;
|
||||
use Intervention\Image\Interfaces\ColorInterface;
|
||||
use Intervention\Image\Interfaces\DecoderInterface;
|
||||
use Intervention\Image\Interfaces\DriverInterface;
|
||||
use Intervention\Image\Interfaces\EncoderInterface;
|
||||
use Intervention\Image\Interfaces\ImageInterface;
|
||||
use Intervention\Image\Interfaces\ModifierInterface;
|
||||
use Intervention\Image\Interfaces\SpecializableInterface;
|
||||
use Intervention\Image\Interfaces\SpecializedInterface;
|
||||
use ReflectionClass;
|
||||
|
||||
abstract class AbstractDriver implements DriverInterface
|
||||
{
|
||||
/**
|
||||
* Driver options
|
||||
*/
|
||||
protected Config $config;
|
||||
|
||||
/**
|
||||
* @throws DriverException
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->config = new Config();
|
||||
$this->checkHealth();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see DriverInterface::config()
|
||||
*/
|
||||
public function config(): Config
|
||||
{
|
||||
return $this->config;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see DriverInterface::handleInput()
|
||||
*/
|
||||
public function handleInput(mixed $input, array $decoders = []): ImageInterface|ColorInterface
|
||||
{
|
||||
return InputHandler::withDecoders($decoders, $this)->handle($input);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see DriverInterface::specialize()
|
||||
*/
|
||||
public function specialize(
|
||||
ModifierInterface|AnalyzerInterface|EncoderInterface|DecoderInterface $object
|
||||
): ModifierInterface|AnalyzerInterface|EncoderInterface|DecoderInterface {
|
||||
// return object directly if no specializing is possible
|
||||
if (!($object instanceof SpecializableInterface)) {
|
||||
return $object;
|
||||
}
|
||||
|
||||
// return directly and only attach driver if object is already specialized
|
||||
if ($object instanceof SpecializedInterface) {
|
||||
$object->setDriver($this);
|
||||
|
||||
return $object;
|
||||
}
|
||||
|
||||
// resolve classname for specializable object
|
||||
$specialized_classname = implode("\\", [
|
||||
(new ReflectionClass($this))->getNamespaceName(), // driver's namespace
|
||||
match (true) {
|
||||
$object instanceof ModifierInterface => 'Modifiers',
|
||||
$object instanceof AnalyzerInterface => 'Analyzers',
|
||||
$object instanceof EncoderInterface => 'Encoders',
|
||||
$object instanceof DecoderInterface => 'Decoders',
|
||||
},
|
||||
$object_shortname = (new ReflectionClass($object))->getShortName(),
|
||||
]);
|
||||
|
||||
// fail if driver specialized classname does not exists
|
||||
if (!class_exists($specialized_classname)) {
|
||||
throw new NotSupportedException(
|
||||
"Class '" . $object_shortname . "' is not supported by " . $this->id() . " driver."
|
||||
);
|
||||
}
|
||||
|
||||
// create a driver specialized object with the specializable properties of generic object
|
||||
$specialized = new $specialized_classname(...$object->specializable());
|
||||
|
||||
// attach driver
|
||||
return $specialized->setDriver($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see DriverInterface::specializeMultiple()
|
||||
*
|
||||
* @throws NotSupportedException
|
||||
* @throws DriverException
|
||||
*/
|
||||
public function specializeMultiple(array $objects): array
|
||||
{
|
||||
return array_map(
|
||||
function (string|object $object): ModifierInterface|AnalyzerInterface|EncoderInterface|DecoderInterface {
|
||||
return $this->specialize(
|
||||
match (true) {
|
||||
is_string($object) => new $object(),
|
||||
is_object($object) => $object,
|
||||
}
|
||||
);
|
||||
},
|
||||
$objects
|
||||
);
|
||||
}
|
||||
}
|
||||
42
upLoadImage/vendor/intervention/image/src/Drivers/AbstractEncoder.php
vendored
Normal file
42
upLoadImage/vendor/intervention/image/src/Drivers/AbstractEncoder.php
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Drivers;
|
||||
|
||||
use Intervention\Image\EncodedImage;
|
||||
use Intervention\Image\Exceptions\RuntimeException;
|
||||
use Intervention\Image\Interfaces\EncodedImageInterface;
|
||||
use Intervention\Image\Interfaces\EncoderInterface;
|
||||
use Intervention\Image\Interfaces\ImageInterface;
|
||||
use Intervention\Image\Traits\CanBuildFilePointer;
|
||||
|
||||
abstract class AbstractEncoder implements EncoderInterface
|
||||
{
|
||||
use CanBuildFilePointer;
|
||||
|
||||
public const DEFAULT_QUALITY = 75;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see EncoderInterface::encode()
|
||||
*/
|
||||
public function encode(ImageInterface $image): EncodedImageInterface
|
||||
{
|
||||
return $image->encode($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build new file pointer, run callback with it and return result as encoded image
|
||||
*
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
protected function createEncodedImage(callable $callback, ?string $mediaType = null): EncodedImage
|
||||
{
|
||||
$pointer = $this->buildFilePointer();
|
||||
$callback($pointer);
|
||||
|
||||
return is_string($mediaType) ? new EncodedImage($pointer, $mediaType) : new EncodedImage($pointer);
|
||||
}
|
||||
}
|
||||
172
upLoadImage/vendor/intervention/image/src/Drivers/AbstractFontProcessor.php
vendored
Normal file
172
upLoadImage/vendor/intervention/image/src/Drivers/AbstractFontProcessor.php
vendored
Normal file
@@ -0,0 +1,172 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Drivers;
|
||||
|
||||
use Intervention\Image\Exceptions\FontException;
|
||||
use Intervention\Image\Geometry\Point;
|
||||
use Intervention\Image\Geometry\Rectangle;
|
||||
use Intervention\Image\Interfaces\FontInterface;
|
||||
use Intervention\Image\Interfaces\FontProcessorInterface;
|
||||
use Intervention\Image\Interfaces\PointInterface;
|
||||
use Intervention\Image\Typography\Line;
|
||||
use Intervention\Image\Typography\TextBlock;
|
||||
|
||||
abstract class AbstractFontProcessor implements FontProcessorInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see FontProcessorInterface::textBlock()
|
||||
*/
|
||||
public function textBlock(string $text, FontInterface $font, PointInterface $position): TextBlock
|
||||
{
|
||||
$lines = $this->wrapTextBlock(new TextBlock($text), $font);
|
||||
$pivot = $this->buildPivot($lines, $font, $position);
|
||||
|
||||
$leading = $this->leading($font);
|
||||
$blockWidth = $this->boxSize((string) $lines->longestLine(), $font)->width();
|
||||
|
||||
$x = $pivot->x();
|
||||
$y = $font->hasFilename() ? $pivot->y() + $this->capHeight($font) : $pivot->y();
|
||||
$xAdjustment = 0;
|
||||
|
||||
// adjust line positions according to alignment
|
||||
foreach ($lines as $line) {
|
||||
$lineBoxSize = $this->boxSize((string) $line, $font);
|
||||
$lineWidth = $lineBoxSize->width() + $lineBoxSize->pivot()->x();
|
||||
$xAdjustment = $font->alignment() === 'left' ? 0 : $blockWidth - $lineWidth;
|
||||
$xAdjustment = $font->alignment() === 'right' ? intval(round($xAdjustment)) : $xAdjustment;
|
||||
$xAdjustment = $font->alignment() === 'center' ? intval(round($xAdjustment / 2)) : $xAdjustment;
|
||||
$position = new Point($x + $xAdjustment, $y);
|
||||
$position->rotate($font->angle(), $pivot);
|
||||
$line->setPosition($position);
|
||||
$y += $leading;
|
||||
}
|
||||
|
||||
return $lines;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see FontProcessorInterface::nativeFontSize()
|
||||
*/
|
||||
public function nativeFontSize(FontInterface $font): float
|
||||
{
|
||||
return $font->size();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see FontProcessorInterface::typographicalSize()
|
||||
*/
|
||||
public function typographicalSize(FontInterface $font): int
|
||||
{
|
||||
return $this->boxSize('Hy', $font)->height();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see FontProcessorInterface::capHeight()
|
||||
*/
|
||||
public function capHeight(FontInterface $font): int
|
||||
{
|
||||
return $this->boxSize('T', $font)->height();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see FontProcessorInterface::leading()
|
||||
*/
|
||||
public function leading(FontInterface $font): int
|
||||
{
|
||||
return intval(round($this->typographicalSize($font) * $font->lineHeight()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Reformat a text block by wrapping each line before the given maximum width
|
||||
*
|
||||
* @throws FontException
|
||||
*/
|
||||
protected function wrapTextBlock(TextBlock $block, FontInterface $font): TextBlock
|
||||
{
|
||||
$newLines = [];
|
||||
foreach ($block as $line) {
|
||||
foreach ($this->wrapLine($line, $font) as $newLine) {
|
||||
$newLines[] = $newLine;
|
||||
}
|
||||
}
|
||||
|
||||
return $block->setLines($newLines);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a line exceeds the given maximum width and wrap it if necessary.
|
||||
* The output will be an array of formatted lines that are all within the
|
||||
* maximum width.
|
||||
*
|
||||
* @throws FontException
|
||||
* @return array<Line>
|
||||
*/
|
||||
protected function wrapLine(Line $line, FontInterface $font): array
|
||||
{
|
||||
// no wrap width - no wrapping
|
||||
if (is_null($font->wrapWidth())) {
|
||||
return [$line];
|
||||
}
|
||||
|
||||
$wrapped = [];
|
||||
$formattedLine = new Line();
|
||||
|
||||
foreach ($line as $word) {
|
||||
// calculate width of newly formatted line
|
||||
$lineWidth = $this->boxSize(match ($formattedLine->count()) {
|
||||
0 => $word,
|
||||
default => $formattedLine . ' ' . $word,
|
||||
}, $font)->width();
|
||||
|
||||
// decide if word fits on current line or a new line must be created
|
||||
if ($line->count() === 1 || $lineWidth <= $font->wrapWidth()) {
|
||||
$formattedLine->add($word);
|
||||
} else {
|
||||
if ($formattedLine->count() !== 0) {
|
||||
$wrapped[] = $formattedLine;
|
||||
}
|
||||
$formattedLine = new Line($word);
|
||||
}
|
||||
}
|
||||
|
||||
$wrapped[] = $formattedLine;
|
||||
|
||||
return $wrapped;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build pivot point of textblock according to the font settings and based on given position
|
||||
*
|
||||
* @throws FontException
|
||||
*/
|
||||
protected function buildPivot(TextBlock $block, FontInterface $font, PointInterface $position): PointInterface
|
||||
{
|
||||
// bounding box
|
||||
$box = new Rectangle(
|
||||
$this->boxSize((string) $block->longestLine(), $font)->width(),
|
||||
$this->leading($font) * ($block->count() - 1) + $this->capHeight($font)
|
||||
);
|
||||
|
||||
// set position
|
||||
$box->setPivot($position);
|
||||
|
||||
// alignment
|
||||
$box->align($font->alignment());
|
||||
$box->valign($font->valignment());
|
||||
$box->rotate($font->angle());
|
||||
|
||||
return $box->last();
|
||||
}
|
||||
}
|
||||
25
upLoadImage/vendor/intervention/image/src/Drivers/AbstractFrame.php
vendored
Normal file
25
upLoadImage/vendor/intervention/image/src/Drivers/AbstractFrame.php
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Drivers;
|
||||
|
||||
use Intervention\Image\Interfaces\FrameInterface;
|
||||
|
||||
abstract class AbstractFrame implements FrameInterface
|
||||
{
|
||||
/**
|
||||
* Show debug info for the current image
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function __debugInfo(): array
|
||||
{
|
||||
return [
|
||||
'delay' => $this->delay(),
|
||||
'left' => $this->offsetLeft(),
|
||||
'top' => $this->offsetTop(),
|
||||
'dispose' => $this->dispose(),
|
||||
];
|
||||
}
|
||||
}
|
||||
23
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Analyzers/ColorspaceAnalyzer.php
vendored
Normal file
23
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Analyzers/ColorspaceAnalyzer.php
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Drivers\Gd\Analyzers;
|
||||
|
||||
use Intervention\Image\Analyzers\ColorspaceAnalyzer as GenericColorspaceAnalyzer;
|
||||
use Intervention\Image\Colors\Rgb\Colorspace;
|
||||
use Intervention\Image\Interfaces\ImageInterface;
|
||||
use Intervention\Image\Interfaces\SpecializedInterface;
|
||||
|
||||
class ColorspaceAnalyzer extends GenericColorspaceAnalyzer implements SpecializedInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see AnalyzerInterface::analyze()
|
||||
*/
|
||||
public function analyze(ImageInterface $image): mixed
|
||||
{
|
||||
return new Colorspace();
|
||||
}
|
||||
}
|
||||
22
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Analyzers/HeightAnalyzer.php
vendored
Normal file
22
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Analyzers/HeightAnalyzer.php
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Drivers\Gd\Analyzers;
|
||||
|
||||
use Intervention\Image\Analyzers\HeightAnalyzer as GenericHeightAnalyzer;
|
||||
use Intervention\Image\Interfaces\ImageInterface;
|
||||
use Intervention\Image\Interfaces\SpecializedInterface;
|
||||
|
||||
class HeightAnalyzer extends GenericHeightAnalyzer implements SpecializedInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see AnalyzerInterface::analyze()
|
||||
*/
|
||||
public function analyze(ImageInterface $image): mixed
|
||||
{
|
||||
return imagesy($image->core()->native());
|
||||
}
|
||||
}
|
||||
51
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Analyzers/PixelColorAnalyzer.php
vendored
Normal file
51
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Analyzers/PixelColorAnalyzer.php
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Drivers\Gd\Analyzers;
|
||||
|
||||
use GdImage;
|
||||
use Intervention\Image\Analyzers\PixelColorAnalyzer as GenericPixelColorAnalyzer;
|
||||
use Intervention\Image\Exceptions\ColorException;
|
||||
use Intervention\Image\Exceptions\GeometryException;
|
||||
use Intervention\Image\Interfaces\ColorInterface;
|
||||
use Intervention\Image\Interfaces\ColorspaceInterface;
|
||||
use Intervention\Image\Interfaces\ImageInterface;
|
||||
use Intervention\Image\Interfaces\SpecializedInterface;
|
||||
|
||||
class PixelColorAnalyzer extends GenericPixelColorAnalyzer implements SpecializedInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see AnalyzerInterface::analyze()
|
||||
*/
|
||||
public function analyze(ImageInterface $image): mixed
|
||||
{
|
||||
return $this->colorAt(
|
||||
$image->colorspace(),
|
||||
$image->core()->frame($this->frame_key)->native()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws GeometryException
|
||||
* @throws ColorException
|
||||
*/
|
||||
protected function colorAt(ColorspaceInterface $colorspace, GdImage $gd): ColorInterface
|
||||
{
|
||||
$index = @imagecolorat($gd, $this->x, $this->y);
|
||||
|
||||
if (!imageistruecolor($gd)) {
|
||||
$index = imagecolorsforindex($gd, $index);
|
||||
}
|
||||
|
||||
if ($index === false) {
|
||||
throw new GeometryException(
|
||||
'The specified position is not in the valid image area.'
|
||||
);
|
||||
}
|
||||
|
||||
return $this->driver()->colorProcessor($colorspace)->nativeToColor($index);
|
||||
}
|
||||
}
|
||||
30
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Analyzers/PixelColorsAnalyzer.php
vendored
Normal file
30
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Analyzers/PixelColorsAnalyzer.php
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Drivers\Gd\Analyzers;
|
||||
|
||||
use Intervention\Image\Collection;
|
||||
use Intervention\Image\Interfaces\ImageInterface;
|
||||
|
||||
class PixelColorsAnalyzer extends PixelColorAnalyzer
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see AnalyzerInterface::analyze()
|
||||
*/
|
||||
public function analyze(ImageInterface $image): mixed
|
||||
{
|
||||
$colors = new Collection();
|
||||
$colorspace = $image->colorspace();
|
||||
|
||||
foreach ($image as $frame) {
|
||||
$colors->push(
|
||||
parent::colorAt($colorspace, $frame->native())
|
||||
);
|
||||
}
|
||||
|
||||
return $colors;
|
||||
}
|
||||
}
|
||||
23
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Analyzers/ResolutionAnalyzer.php
vendored
Normal file
23
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Analyzers/ResolutionAnalyzer.php
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Drivers\Gd\Analyzers;
|
||||
|
||||
use Intervention\Image\Analyzers\ResolutionAnalyzer as GenericResolutionAnalyzer;
|
||||
use Intervention\Image\Interfaces\ImageInterface;
|
||||
use Intervention\Image\Interfaces\SpecializedInterface;
|
||||
use Intervention\Image\Resolution;
|
||||
|
||||
class ResolutionAnalyzer extends GenericResolutionAnalyzer implements SpecializedInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see AnalyzerInterface::analyze()
|
||||
*/
|
||||
public function analyze(ImageInterface $image): mixed
|
||||
{
|
||||
return new Resolution(...imageresolution($image->core()->native()));
|
||||
}
|
||||
}
|
||||
22
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Analyzers/WidthAnalyzer.php
vendored
Normal file
22
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Analyzers/WidthAnalyzer.php
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Drivers\Gd\Analyzers;
|
||||
|
||||
use Intervention\Image\Analyzers\WidthAnalyzer as GenericWidthAnalyzer;
|
||||
use Intervention\Image\Interfaces\ImageInterface;
|
||||
use Intervention\Image\Interfaces\SpecializedInterface;
|
||||
|
||||
class WidthAnalyzer extends GenericWidthAnalyzer implements SpecializedInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see AnalyzerInterface::analyze()
|
||||
*/
|
||||
public function analyze(ImageInterface $image): mixed
|
||||
{
|
||||
return imagesx($image->core()->native());
|
||||
}
|
||||
}
|
||||
90
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Cloner.php
vendored
Normal file
90
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Cloner.php
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Drivers\Gd;
|
||||
|
||||
use GdImage;
|
||||
use Intervention\Image\Colors\Rgb\Channels\Alpha;
|
||||
use Intervention\Image\Colors\Rgb\Color;
|
||||
use Intervention\Image\Exceptions\ColorException;
|
||||
use Intervention\Image\Geometry\Rectangle;
|
||||
use Intervention\Image\Interfaces\ColorInterface;
|
||||
use Intervention\Image\Interfaces\SizeInterface;
|
||||
|
||||
class Cloner
|
||||
{
|
||||
/**
|
||||
* Create a clone of the given GdImage
|
||||
*
|
||||
* @throws ColorException
|
||||
*/
|
||||
public static function clone(GdImage $gd): GdImage
|
||||
{
|
||||
// create empty canvas with same size
|
||||
$clone = static::cloneEmpty($gd);
|
||||
|
||||
// transfer actual image to clone
|
||||
imagecopy($clone, $gd, 0, 0, 0, 0, imagesx($gd), imagesy($gd));
|
||||
|
||||
return $clone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an "empty" clone of the given GdImage
|
||||
*
|
||||
* This only retains the basic data without transferring the actual image.
|
||||
* It is optionally possible to change the size of the result and set a
|
||||
* background color.
|
||||
*
|
||||
* @throws ColorException
|
||||
*/
|
||||
public static function cloneEmpty(
|
||||
GdImage $gd,
|
||||
?SizeInterface $size = null,
|
||||
ColorInterface $background = new Color(255, 255, 255, 0)
|
||||
): GdImage {
|
||||
// define size
|
||||
$size = $size ?: new Rectangle(imagesx($gd), imagesy($gd));
|
||||
|
||||
// create new gd image with same size or new given size
|
||||
$clone = imagecreatetruecolor($size->width(), $size->height());
|
||||
|
||||
// copy resolution to clone
|
||||
$resolution = imageresolution($gd);
|
||||
if (is_array($resolution) && array_key_exists(0, $resolution) && array_key_exists(1, $resolution)) {
|
||||
imageresolution($clone, $resolution[0], $resolution[1]);
|
||||
}
|
||||
|
||||
// fill with background
|
||||
$processor = new ColorProcessor();
|
||||
imagefill($clone, 0, 0, $processor->colorToNative($background));
|
||||
imagealphablending($clone, true);
|
||||
imagesavealpha($clone, true);
|
||||
|
||||
// set background image as transparent if alpha channel value if color is below .5
|
||||
// comes into effect when the end format only supports binary transparency (like GIF)
|
||||
if ($background->channel(Alpha::class)->value() < 128) {
|
||||
imagecolortransparent($clone, $processor->colorToNative($background));
|
||||
}
|
||||
|
||||
return $clone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a clone of an GdImage that is positioned on the specified background color.
|
||||
* Possible transparent areas are mixed with this color.
|
||||
*
|
||||
* @throws ColorException
|
||||
*/
|
||||
public static function cloneBlended(GdImage $gd, ColorInterface $background): GdImage
|
||||
{
|
||||
// create empty canvas with same size
|
||||
$clone = static::cloneEmpty($gd, background: $background);
|
||||
|
||||
// transfer actual image to clone
|
||||
imagecopy($clone, $gd, 0, 0, 0, 0, imagesx($gd), imagesy($gd));
|
||||
|
||||
return $clone;
|
||||
}
|
||||
}
|
||||
148
upLoadImage/vendor/intervention/image/src/Drivers/Gd/ColorProcessor.php
vendored
Normal file
148
upLoadImage/vendor/intervention/image/src/Drivers/Gd/ColorProcessor.php
vendored
Normal file
@@ -0,0 +1,148 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
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\Color;
|
||||
use Intervention\Image\Colors\Rgb\Colorspace;
|
||||
use Intervention\Image\Exceptions\ColorException;
|
||||
use Intervention\Image\Interfaces\ColorInterface;
|
||||
use Intervention\Image\Interfaces\ColorProcessorInterface;
|
||||
use Intervention\Image\Interfaces\ColorspaceInterface;
|
||||
|
||||
class ColorProcessor implements ColorProcessorInterface
|
||||
{
|
||||
/**
|
||||
* Create new color processor object
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(protected ColorspaceInterface $colorspace = new Colorspace())
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see ColorProcessorInterface::colorToNative()
|
||||
*/
|
||||
public function colorToNative(ColorInterface $color): int
|
||||
{
|
||||
// convert color to colorspace
|
||||
$color = $color->convertTo($this->colorspace);
|
||||
|
||||
// gd only supports rgb so the channels can be accessed directly
|
||||
$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;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see ColorProcessorInterface::nativeToColor()
|
||||
*/
|
||||
public function nativeToColor(mixed $value): ColorInterface
|
||||
{
|
||||
if (!is_int($value) && !is_array($value)) {
|
||||
throw new ColorException('GD driver can only decode colors in integer and array format.');
|
||||
}
|
||||
|
||||
if (is_array($value)) {
|
||||
// array conversion
|
||||
if (!$this->isValidArrayColor($value)) {
|
||||
throw new ColorException(
|
||||
'GD driver can only decode array color format array{red: int, green: int, blue: int, alpha: int}.',
|
||||
);
|
||||
}
|
||||
|
||||
$r = $value['red'];
|
||||
$g = $value['green'];
|
||||
$b = $value['blue'];
|
||||
$a = $value['alpha'];
|
||||
} else {
|
||||
// integer conversion
|
||||
$a = ($value >> 24) & 0xFF;
|
||||
$r = ($value >> 16) & 0xFF;
|
||||
$g = ($value >> 8) & 0xFF;
|
||||
$b = $value & 0xFF;
|
||||
}
|
||||
|
||||
// convert gd apha integer to intervention alpha integer
|
||||
// ([opaque]0-127[transparent]) to ([opaque]255-0[transparent])
|
||||
$a = (int) static::convertRange($a, 127, 0, 0, 255);
|
||||
|
||||
return new Color($r, $g, $b, $a);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert input in range (min) to (max) to the corresponding value
|
||||
* in target range (targetMin) to (targetMax).
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if given array is valid color format
|
||||
* array{red: int, green: int, blue: int, alpha: int}
|
||||
* i.e. result of imagecolorsforindex()
|
||||
*
|
||||
* @param array<mixed> $color
|
||||
*/
|
||||
private function isValidArrayColor(array $color): bool
|
||||
{
|
||||
if (!array_key_exists('red', $color)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!array_key_exists('green', $color)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!array_key_exists('blue', $color)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!array_key_exists('alpha', $color)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!is_int($color['red'])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!is_int($color['green'])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!is_int($color['blue'])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!is_int($color['alpha'])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
117
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Core.php
vendored
Normal file
117
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Core.php
vendored
Normal file
@@ -0,0 +1,117 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Drivers\Gd;
|
||||
|
||||
use Intervention\Image\Collection;
|
||||
use Intervention\Image\Exceptions\AnimationException;
|
||||
use Intervention\Image\Interfaces\CoreInterface;
|
||||
use Intervention\Image\Interfaces\FrameInterface;
|
||||
|
||||
class Core extends Collection implements CoreInterface
|
||||
{
|
||||
protected int $loops = 0;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see CoreInterface::add()
|
||||
*/
|
||||
public function add(FrameInterface $frame): CoreInterface
|
||||
{
|
||||
$this->push($frame);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see CoreInterface::native()
|
||||
*/
|
||||
public function native(): mixed
|
||||
{
|
||||
return $this->first()->native();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see CoreInterface::setNative()
|
||||
*/
|
||||
public function setNative(mixed $native): self
|
||||
{
|
||||
$this->empty()->push(new Frame($native));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see CoreInterface::frame()
|
||||
*/
|
||||
public function frame(int $position): FrameInterface
|
||||
{
|
||||
$frame = $this->getAtPosition($position);
|
||||
|
||||
if (!($frame instanceof FrameInterface)) {
|
||||
throw new AnimationException('Frame #' . $position . ' could not be found in the image.');
|
||||
}
|
||||
|
||||
return $frame;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see CoreInterface::loops()
|
||||
*/
|
||||
public function loops(): int
|
||||
{
|
||||
return $this->loops;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see CoreInterface::setLoops()
|
||||
*/
|
||||
public function setLoops(int $loops): self
|
||||
{
|
||||
$this->loops = $loops;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see CollectionInterface::first()
|
||||
*/
|
||||
public function first(): FrameInterface
|
||||
{
|
||||
return parent::first();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see CollectionInterface::last()
|
||||
*/
|
||||
public function last(): FrameInterface
|
||||
{
|
||||
return parent::last();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clone instance
|
||||
*/
|
||||
public function __clone(): void
|
||||
{
|
||||
foreach ($this->items as $key => $frame) {
|
||||
$this->items[$key] = clone $frame;
|
||||
}
|
||||
}
|
||||
}
|
||||
57
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Decoders/AbstractDecoder.php
vendored
Normal file
57
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Decoders/AbstractDecoder.php
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Drivers\Gd\Decoders;
|
||||
|
||||
use Intervention\Image\Drivers\SpecializableDecoder;
|
||||
use Intervention\Image\Exceptions\DecoderException;
|
||||
use Intervention\Image\Exceptions\NotSupportedException;
|
||||
use Intervention\Image\Interfaces\SpecializedInterface;
|
||||
use Intervention\Image\MediaType;
|
||||
use ValueError;
|
||||
|
||||
abstract class AbstractDecoder extends SpecializableDecoder implements SpecializedInterface
|
||||
{
|
||||
/**
|
||||
* Return media (mime) type of the file at given file path
|
||||
*
|
||||
* @throws DecoderException
|
||||
* @throws NotSupportedException
|
||||
*/
|
||||
protected function getMediaTypeByFilePath(string $filepath): MediaType
|
||||
{
|
||||
$info = @getimagesize($filepath);
|
||||
|
||||
if (!is_array($info)) {
|
||||
throw new DecoderException('Unable to detect media (MIME) from data in file path.');
|
||||
}
|
||||
|
||||
try {
|
||||
return MediaType::from($info['mime']);
|
||||
} catch (ValueError) {
|
||||
throw new NotSupportedException('Unsupported media type (MIME) ' . $info['mime'] . '.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return media (mime) type of the given image data
|
||||
*
|
||||
* @throws DecoderException
|
||||
* @throws NotSupportedException
|
||||
*/
|
||||
protected function getMediaTypeByBinary(string $data): MediaType
|
||||
{
|
||||
$info = @getimagesizefromstring($data);
|
||||
|
||||
if (!is_array($info)) {
|
||||
throw new DecoderException('Unable to detect media (MIME) from binary data.');
|
||||
}
|
||||
|
||||
try {
|
||||
return MediaType::from($info['mime']);
|
||||
} catch (ValueError) {
|
||||
throw new NotSupportedException('Unsupported media type (MIME) ' . $info['mime'] . '.');
|
||||
}
|
||||
}
|
||||
}
|
||||
27
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Decoders/Base64ImageDecoder.php
vendored
Normal file
27
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Decoders/Base64ImageDecoder.php
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Drivers\Gd\Decoders;
|
||||
|
||||
use Intervention\Image\Exceptions\DecoderException;
|
||||
use Intervention\Image\Interfaces\ColorInterface;
|
||||
use Intervention\Image\Interfaces\DecoderInterface;
|
||||
use Intervention\Image\Interfaces\ImageInterface;
|
||||
|
||||
class Base64ImageDecoder extends BinaryImageDecoder implements DecoderInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see DecoderInterface::decode()
|
||||
*/
|
||||
public function decode(mixed $input): ImageInterface|ColorInterface
|
||||
{
|
||||
if (!$this->isValidBase64($input)) {
|
||||
throw new DecoderException('Unable to decode input');
|
||||
}
|
||||
|
||||
return parent::decode(base64_decode((string) $input));
|
||||
}
|
||||
}
|
||||
68
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Decoders/BinaryImageDecoder.php
vendored
Normal file
68
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Decoders/BinaryImageDecoder.php
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Drivers\Gd\Decoders;
|
||||
|
||||
use Intervention\Image\Exceptions\RuntimeException;
|
||||
use Intervention\Image\Interfaces\ColorInterface;
|
||||
use Intervention\Image\Interfaces\DecoderInterface;
|
||||
use Intervention\Image\Interfaces\ImageInterface;
|
||||
use Intervention\Image\Exceptions\DecoderException;
|
||||
use Intervention\Image\Format;
|
||||
use Intervention\Image\Modifiers\AlignRotationModifier;
|
||||
|
||||
class BinaryImageDecoder extends NativeObjectDecoder implements DecoderInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see DecoderInterface::decode()
|
||||
*/
|
||||
public function decode(mixed $input): ImageInterface|ColorInterface
|
||||
{
|
||||
if (!is_string($input)) {
|
||||
throw new DecoderException('Unable to decode input');
|
||||
}
|
||||
|
||||
return match ($this->isGifFormat($input)) {
|
||||
true => $this->decodeGif($input),
|
||||
default => $this->decodeBinary($input),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode image from given binary data
|
||||
*
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
private function decodeBinary(string $input): ImageInterface
|
||||
{
|
||||
$gd = @imagecreatefromstring($input);
|
||||
|
||||
if ($gd === false) {
|
||||
throw new DecoderException('Unable to decode input');
|
||||
}
|
||||
|
||||
// create image instance
|
||||
$image = parent::decode($gd);
|
||||
|
||||
// get media type
|
||||
$mediaType = $this->getMediaTypeByBinary($input);
|
||||
|
||||
// extract & set exif data for appropriate formats
|
||||
if (in_array($mediaType->format(), [Format::JPEG, Format::TIFF])) {
|
||||
$image->setExif($this->extractExifData($input));
|
||||
}
|
||||
|
||||
// set mediaType on origin
|
||||
$image->origin()->setMediaType($mediaType);
|
||||
|
||||
// adjust image orientation
|
||||
if ($this->driver()->config()->autoOrientation) {
|
||||
$image->modify(new AlignRotationModifier());
|
||||
}
|
||||
|
||||
return $image;
|
||||
}
|
||||
}
|
||||
37
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Decoders/DataUriImageDecoder.php
vendored
Normal file
37
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Decoders/DataUriImageDecoder.php
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Drivers\Gd\Decoders;
|
||||
|
||||
use Intervention\Image\Exceptions\DecoderException;
|
||||
use Intervention\Image\Interfaces\ColorInterface;
|
||||
use Intervention\Image\Interfaces\DecoderInterface;
|
||||
use Intervention\Image\Interfaces\ImageInterface;
|
||||
|
||||
class DataUriImageDecoder extends BinaryImageDecoder implements DecoderInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see DecoderInterface::decode()
|
||||
*/
|
||||
public function decode(mixed $input): ImageInterface|ColorInterface
|
||||
{
|
||||
if (!is_string($input)) {
|
||||
throw new DecoderException('Unable to decode input');
|
||||
}
|
||||
|
||||
$uri = $this->parseDataUri($input);
|
||||
|
||||
if (!$uri->isValid()) {
|
||||
throw new DecoderException('Unable to decode input');
|
||||
}
|
||||
|
||||
if ($uri->isBase64Encoded()) {
|
||||
return parent::decode(base64_decode($uri->data()));
|
||||
}
|
||||
|
||||
return parent::decode(urldecode($uri->data()));
|
||||
}
|
||||
}
|
||||
27
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Decoders/EncodedImageObjectDecoder.php
vendored
Normal file
27
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Decoders/EncodedImageObjectDecoder.php
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Drivers\Gd\Decoders;
|
||||
|
||||
use Intervention\Image\EncodedImage;
|
||||
use Intervention\Image\Exceptions\DecoderException;
|
||||
use Intervention\Image\Interfaces\ImageInterface;
|
||||
use Intervention\Image\Interfaces\ColorInterface;
|
||||
|
||||
class EncodedImageObjectDecoder extends BinaryImageDecoder
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see DecoderInterface::decode()
|
||||
*/
|
||||
public function decode(mixed $input): ImageInterface|ColorInterface
|
||||
{
|
||||
if (!is_a($input, EncodedImage::class)) {
|
||||
throw new DecoderException('Unable to decode input');
|
||||
}
|
||||
|
||||
return parent::decode($input->toString());
|
||||
}
|
||||
}
|
||||
60
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Decoders/FilePathImageDecoder.php
vendored
Normal file
60
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Decoders/FilePathImageDecoder.php
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Drivers\Gd\Decoders;
|
||||
|
||||
use Intervention\Image\Exceptions\DecoderException;
|
||||
use Intervention\Image\Format;
|
||||
use Intervention\Image\Interfaces\ColorInterface;
|
||||
use Intervention\Image\Interfaces\DecoderInterface;
|
||||
use Intervention\Image\Interfaces\ImageInterface;
|
||||
use Intervention\Image\Modifiers\AlignRotationModifier;
|
||||
|
||||
class FilePathImageDecoder extends NativeObjectDecoder implements DecoderInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see DecoderInterface::decode()
|
||||
*/
|
||||
public function decode(mixed $input): ImageInterface|ColorInterface
|
||||
{
|
||||
if (!$this->isFile($input)) {
|
||||
throw new DecoderException('Unable to decode input');
|
||||
}
|
||||
|
||||
// detect media (mime) type
|
||||
$mediaType = $this->getMediaTypeByFilePath($input);
|
||||
|
||||
$image = match ($mediaType->format()) {
|
||||
// gif files might be animated and therefore cannot
|
||||
// be handled by the standard GD decoder.
|
||||
Format::GIF => $this->decodeGif($input),
|
||||
default => parent::decode(match ($mediaType->format()) {
|
||||
Format::JPEG => @imagecreatefromjpeg($input),
|
||||
Format::WEBP => @imagecreatefromwebp($input),
|
||||
Format::PNG => @imagecreatefrompng($input),
|
||||
Format::AVIF => @imagecreatefromavif($input),
|
||||
Format::BMP => @imagecreatefrombmp($input),
|
||||
default => throw new DecoderException('Unable to decode input'),
|
||||
}),
|
||||
};
|
||||
|
||||
// set file path & mediaType on origin
|
||||
$image->origin()->setFilePath($input);
|
||||
$image->origin()->setMediaType($mediaType);
|
||||
|
||||
// extract exif for the appropriate formats
|
||||
if ($mediaType->format() === Format::JPEG) {
|
||||
$image->setExif($this->extractExifData($input));
|
||||
}
|
||||
|
||||
// adjust image orientation
|
||||
if ($this->driver()->config()->autoOrientation) {
|
||||
$image->modify(new AlignRotationModifier());
|
||||
}
|
||||
|
||||
return $image;
|
||||
}
|
||||
}
|
||||
32
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Decoders/FilePointerImageDecoder.php
vendored
Normal file
32
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Decoders/FilePointerImageDecoder.php
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Drivers\Gd\Decoders;
|
||||
|
||||
use Intervention\Image\Exceptions\DecoderException;
|
||||
use Intervention\Image\Interfaces\ColorInterface;
|
||||
use Intervention\Image\Interfaces\ImageInterface;
|
||||
|
||||
class FilePointerImageDecoder extends BinaryImageDecoder
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see DecoderInterface::decode()
|
||||
*/
|
||||
public function decode(mixed $input): ImageInterface|ColorInterface
|
||||
{
|
||||
if (!is_resource($input) || !in_array(get_resource_type($input), ['file', 'stream'])) {
|
||||
throw new DecoderException('Unable to decode input');
|
||||
}
|
||||
|
||||
$contents = '';
|
||||
@rewind($input);
|
||||
while (!feof($input)) {
|
||||
$contents .= fread($input, 1024);
|
||||
}
|
||||
|
||||
return parent::decode($contents);
|
||||
}
|
||||
}
|
||||
109
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Decoders/NativeObjectDecoder.php
vendored
Normal file
109
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Decoders/NativeObjectDecoder.php
vendored
Normal file
@@ -0,0 +1,109 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Drivers\Gd\Decoders;
|
||||
|
||||
use Exception;
|
||||
use GdImage;
|
||||
use Intervention\Gif\Decoder as GifDecoder;
|
||||
use Intervention\Gif\Splitter as GifSplitter;
|
||||
use Intervention\Image\Drivers\Gd\Core;
|
||||
use Intervention\Image\Drivers\Gd\Frame;
|
||||
use Intervention\Image\Exceptions\DecoderException;
|
||||
use Intervention\Image\Exceptions\RuntimeException;
|
||||
use Intervention\Image\Image;
|
||||
use Intervention\Image\Interfaces\ColorInterface;
|
||||
use Intervention\Image\Interfaces\ImageInterface;
|
||||
|
||||
class NativeObjectDecoder extends AbstractDecoder
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see DecoderInterface::decode()
|
||||
*/
|
||||
public function decode(mixed $input): ImageInterface|ColorInterface
|
||||
{
|
||||
if (!is_object($input)) {
|
||||
throw new DecoderException('Unable to decode input');
|
||||
}
|
||||
|
||||
if (!($input instanceof GdImage)) {
|
||||
throw new DecoderException('Unable to decode input');
|
||||
}
|
||||
|
||||
if (!imageistruecolor($input)) {
|
||||
imagepalettetotruecolor($input);
|
||||
}
|
||||
|
||||
imagesavealpha($input, true);
|
||||
|
||||
// build image instance
|
||||
return new Image(
|
||||
$this->driver(),
|
||||
new Core([
|
||||
new Frame($input)
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode image from given GIF source which can be either a file path or binary data
|
||||
*
|
||||
* Depending on the configuration, this is taken over by the native GD function
|
||||
* or, if animations are required, by our own extended decoder.
|
||||
*
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
protected function decodeGif(mixed $input): ImageInterface
|
||||
{
|
||||
// create non-animated image depending on config
|
||||
if (!$this->driver()->config()->decodeAnimation) {
|
||||
$native = match (true) {
|
||||
$this->isGifFormat($input) => @imagecreatefromstring($input),
|
||||
default => @imagecreatefromgif($input),
|
||||
};
|
||||
|
||||
if ($native === false) {
|
||||
throw new DecoderException('Unable to decode input.');
|
||||
}
|
||||
|
||||
$image = self::decode($native);
|
||||
$image->origin()->setMediaType('image/gif');
|
||||
|
||||
return $image;
|
||||
}
|
||||
|
||||
try {
|
||||
// create empty core
|
||||
$core = new Core();
|
||||
|
||||
$gif = GifDecoder::decode($input);
|
||||
$splitter = GifSplitter::create($gif)->split();
|
||||
$delays = $splitter->getDelays();
|
||||
|
||||
// set loops on core
|
||||
if ($loops = $gif->getMainApplicationExtension()?->getLoops()) {
|
||||
$core->setLoops($loops);
|
||||
}
|
||||
|
||||
// add GDImage instances to core
|
||||
foreach ($splitter->coalesceToResources() as $key => $native) {
|
||||
$core->push(
|
||||
new Frame($native, $delays[$key] / 100)
|
||||
);
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
throw new DecoderException($e->getMessage(), $e->getCode(), $e);
|
||||
}
|
||||
|
||||
// create (possibly) animated image
|
||||
$image = new Image($this->driver(), $core);
|
||||
|
||||
// set media type
|
||||
$image->origin()->setMediaType('image/gif');
|
||||
|
||||
return $image;
|
||||
}
|
||||
}
|
||||
28
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Decoders/SplFileInfoImageDecoder.php
vendored
Normal file
28
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Decoders/SplFileInfoImageDecoder.php
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Drivers\Gd\Decoders;
|
||||
|
||||
use SplFileInfo;
|
||||
use Intervention\Image\Exceptions\DecoderException;
|
||||
use Intervention\Image\Interfaces\ColorInterface;
|
||||
use Intervention\Image\Interfaces\DecoderInterface;
|
||||
use Intervention\Image\Interfaces\ImageInterface;
|
||||
|
||||
class SplFileInfoImageDecoder extends FilePathImageDecoder implements DecoderInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see DecoderInterface::decode()
|
||||
*/
|
||||
public function decode(mixed $input): ImageInterface|ColorInterface
|
||||
{
|
||||
if (!is_a($input, SplFileInfo::class)) {
|
||||
throw new DecoderException('Unable to decode input');
|
||||
}
|
||||
|
||||
return parent::decode($input->getRealPath());
|
||||
}
|
||||
}
|
||||
163
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Driver.php
vendored
Normal file
163
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Driver.php
vendored
Normal file
@@ -0,0 +1,163 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Drivers\Gd;
|
||||
|
||||
use Intervention\Image\Drivers\AbstractDriver;
|
||||
use Intervention\Image\Exceptions\DriverException;
|
||||
use Intervention\Image\Exceptions\RuntimeException;
|
||||
use Intervention\Image\Format;
|
||||
use Intervention\Image\FileExtension;
|
||||
use Intervention\Image\Image;
|
||||
use Intervention\Image\Interfaces\ColorProcessorInterface;
|
||||
use Intervention\Image\Interfaces\ColorspaceInterface;
|
||||
use Intervention\Image\Interfaces\DriverInterface;
|
||||
use Intervention\Image\Interfaces\FontProcessorInterface;
|
||||
use Intervention\Image\Interfaces\ImageInterface;
|
||||
use Intervention\Image\MediaType;
|
||||
|
||||
class Driver extends AbstractDriver
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see DriverInterface::id()
|
||||
*/
|
||||
public function id(): string
|
||||
{
|
||||
return 'GD';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see DriverInterface::checkHealth()
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function checkHealth(): void
|
||||
{
|
||||
if (!extension_loaded('gd') || !function_exists('gd_info')) {
|
||||
throw new DriverException(
|
||||
'GD PHP extension must be installed to use this driver.'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see DriverInterface::createImage()
|
||||
*/
|
||||
public function createImage(int $width, int $height): ImageInterface
|
||||
{
|
||||
// build new transparent GDImage
|
||||
$data = imagecreatetruecolor($width, $height);
|
||||
imagesavealpha($data, true);
|
||||
$background = imagecolorallocatealpha($data, 255, 255, 255, 127);
|
||||
imagealphablending($data, false);
|
||||
imagefill($data, 0, 0, $background);
|
||||
imagecolortransparent($data, $background);
|
||||
|
||||
return new Image(
|
||||
$this,
|
||||
new Core([
|
||||
new Frame($data)
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see DriverInterface::createAnimation()
|
||||
*
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function createAnimation(callable $init): ImageInterface
|
||||
{
|
||||
$animation = new class ($this)
|
||||
{
|
||||
public function __construct(
|
||||
protected DriverInterface $driver,
|
||||
public Core $core = new Core()
|
||||
) {
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function add(mixed $source, float $delay = 1): self
|
||||
{
|
||||
$this->core->add(
|
||||
$this->driver->handleInput($source)->core()->first()->setDelay($delay)
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function __invoke(): ImageInterface
|
||||
{
|
||||
return new Image(
|
||||
$this->driver,
|
||||
$this->core
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
$init($animation);
|
||||
|
||||
return call_user_func($animation);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see DriverInterface::colorProcessor()
|
||||
*/
|
||||
public function colorProcessor(ColorspaceInterface $colorspace): ColorProcessorInterface
|
||||
{
|
||||
return new ColorProcessor($colorspace);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see DriverInterface::fontProcessor()
|
||||
*/
|
||||
public function fontProcessor(): FontProcessorInterface
|
||||
{
|
||||
return new FontProcessor();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see DriverInterface::supports()
|
||||
*/
|
||||
public function supports(string|Format|FileExtension|MediaType $identifier): bool
|
||||
{
|
||||
return match (Format::tryCreate($identifier)) {
|
||||
Format::JPEG => boolval(imagetypes() & IMG_JPEG),
|
||||
Format::WEBP => boolval(imagetypes() & IMG_WEBP),
|
||||
Format::GIF => boolval(imagetypes() & IMG_GIF),
|
||||
Format::PNG => boolval(imagetypes() & IMG_PNG),
|
||||
Format::AVIF => boolval(imagetypes() & IMG_AVIF),
|
||||
Format::BMP => boolval(imagetypes() & IMG_BMP),
|
||||
default => false,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Return version of GD library
|
||||
*/
|
||||
public static function version(): string
|
||||
{
|
||||
return gd_info()['GD Version'];
|
||||
}
|
||||
}
|
||||
25
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Encoders/AvifEncoder.php
vendored
Normal file
25
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Encoders/AvifEncoder.php
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Drivers\Gd\Encoders;
|
||||
|
||||
use Intervention\Image\EncodedImage;
|
||||
use Intervention\Image\Encoders\AvifEncoder as GenericAvifEncoder;
|
||||
use Intervention\Image\Interfaces\ImageInterface;
|
||||
use Intervention\Image\Interfaces\SpecializedInterface;
|
||||
|
||||
class AvifEncoder extends GenericAvifEncoder implements SpecializedInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see EncoderInterface::encode()
|
||||
*/
|
||||
public function encode(ImageInterface $image): EncodedImage
|
||||
{
|
||||
return $this->createEncodedImage(function ($pointer) use ($image): void {
|
||||
imageavif($image->core()->native(), $pointer, $this->quality);
|
||||
}, 'image/avif');
|
||||
}
|
||||
}
|
||||
25
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Encoders/BmpEncoder.php
vendored
Normal file
25
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Encoders/BmpEncoder.php
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Drivers\Gd\Encoders;
|
||||
|
||||
use Intervention\Image\EncodedImage;
|
||||
use Intervention\Image\Encoders\BmpEncoder as GenericBmpEncoder;
|
||||
use Intervention\Image\Interfaces\ImageInterface;
|
||||
use Intervention\Image\Interfaces\SpecializedInterface;
|
||||
|
||||
class BmpEncoder extends GenericBmpEncoder implements SpecializedInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see EncoderInterface::encode()
|
||||
*/
|
||||
public function encode(ImageInterface $image): EncodedImage
|
||||
{
|
||||
return $this->createEncodedImage(function ($pointer) use ($image): void {
|
||||
imagebmp($image->core()->native(), $pointer, false);
|
||||
}, 'image/bmp');
|
||||
}
|
||||
}
|
||||
64
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Encoders/GifEncoder.php
vendored
Normal file
64
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Encoders/GifEncoder.php
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Drivers\Gd\Encoders;
|
||||
|
||||
use Exception;
|
||||
use Intervention\Gif\Builder as GifBuilder;
|
||||
use Intervention\Image\Drivers\Gd\Cloner;
|
||||
use Intervention\Image\EncodedImage;
|
||||
use Intervention\Image\Encoders\GifEncoder as GenericGifEncoder;
|
||||
use Intervention\Image\Exceptions\EncoderException;
|
||||
use Intervention\Image\Exceptions\RuntimeException;
|
||||
use Intervention\Image\Interfaces\ImageInterface;
|
||||
use Intervention\Image\Interfaces\SpecializedInterface;
|
||||
|
||||
class GifEncoder extends GenericGifEncoder implements SpecializedInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see EncoderInterface::encode()
|
||||
*/
|
||||
public function encode(ImageInterface $image): EncodedImage
|
||||
{
|
||||
if ($image->isAnimated()) {
|
||||
return $this->encodeAnimated($image);
|
||||
}
|
||||
|
||||
$gd = Cloner::clone($image->core()->native());
|
||||
|
||||
return $this->createEncodedImage(function ($pointer) use ($gd): void {
|
||||
imageinterlace($gd, $this->interlaced);
|
||||
imagegif($gd, $pointer);
|
||||
}, 'image/gif');
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
protected function encodeAnimated(ImageInterface $image): EncodedImage
|
||||
{
|
||||
try {
|
||||
$builder = GifBuilder::canvas(
|
||||
$image->width(),
|
||||
$image->height()
|
||||
);
|
||||
|
||||
foreach ($image as $frame) {
|
||||
$builder->addFrame(
|
||||
source: $this->encode($frame->toImage($image->driver()))->toFilePointer(),
|
||||
delay: $frame->delay(),
|
||||
interlaced: $this->interlaced
|
||||
);
|
||||
}
|
||||
|
||||
$builder->setLoops($image->loops());
|
||||
|
||||
return new EncodedImage($builder->encode(), 'image/gif');
|
||||
} catch (Exception $e) {
|
||||
throw new EncoderException($e->getMessage(), $e->getCode(), $e);
|
||||
}
|
||||
}
|
||||
}
|
||||
36
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Encoders/JpegEncoder.php
vendored
Normal file
36
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Encoders/JpegEncoder.php
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Drivers\Gd\Encoders;
|
||||
|
||||
use Intervention\Image\Drivers\Gd\Cloner;
|
||||
use Intervention\Image\Encoders\JpegEncoder as GenericJpegEncoder;
|
||||
use Intervention\Image\EncodedImage;
|
||||
use Intervention\Image\Interfaces\ImageInterface;
|
||||
use Intervention\Image\Interfaces\SpecializedInterface;
|
||||
|
||||
class JpegEncoder extends GenericJpegEncoder implements SpecializedInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see EncoderInterface::encode()
|
||||
*/
|
||||
public function encode(ImageInterface $image): EncodedImage
|
||||
{
|
||||
$blendingColor = $this->driver()->handleInput(
|
||||
$this->driver()->config()->blendingColor
|
||||
);
|
||||
|
||||
$output = Cloner::cloneBlended(
|
||||
$image->core()->native(),
|
||||
background: $blendingColor
|
||||
);
|
||||
|
||||
return $this->createEncodedImage(function ($pointer) use ($output): void {
|
||||
imageinterlace($output, $this->progressive);
|
||||
imagejpeg($output, $pointer, $this->quality);
|
||||
}, 'image/jpeg');
|
||||
}
|
||||
}
|
||||
52
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Encoders/PngEncoder.php
vendored
Normal file
52
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Encoders/PngEncoder.php
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Drivers\Gd\Encoders;
|
||||
|
||||
use GdImage;
|
||||
use Intervention\Image\Drivers\Gd\Cloner;
|
||||
use Intervention\Image\EncodedImage;
|
||||
use Intervention\Image\Encoders\PngEncoder as GenericPngEncoder;
|
||||
use Intervention\Image\Exceptions\AnimationException;
|
||||
use Intervention\Image\Exceptions\ColorException;
|
||||
use Intervention\Image\Exceptions\RuntimeException;
|
||||
use Intervention\Image\Interfaces\ImageInterface;
|
||||
use Intervention\Image\Interfaces\SpecializedInterface;
|
||||
|
||||
class PngEncoder extends GenericPngEncoder implements SpecializedInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see EncoderInterface::encode()
|
||||
*/
|
||||
public function encode(ImageInterface $image): EncodedImage
|
||||
{
|
||||
$output = $this->prepareOutput($image);
|
||||
|
||||
return $this->createEncodedImage(function ($pointer) use ($output): void {
|
||||
imageinterlace($output, $this->interlaced);
|
||||
imagepng($output, $pointer, -1);
|
||||
}, 'image/png');
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare given image instance for PNG format output according to encoder settings
|
||||
*
|
||||
* @throws RuntimeException
|
||||
* @throws ColorException
|
||||
* @throws AnimationException
|
||||
*/
|
||||
private function prepareOutput(ImageInterface $image): GdImage
|
||||
{
|
||||
if ($this->indexed) {
|
||||
$output = clone $image;
|
||||
$output->reduceColors(255);
|
||||
|
||||
return $output->core()->native();
|
||||
}
|
||||
|
||||
return Cloner::clone($image->core()->native());
|
||||
}
|
||||
}
|
||||
27
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Encoders/WebpEncoder.php
vendored
Normal file
27
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Encoders/WebpEncoder.php
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Drivers\Gd\Encoders;
|
||||
|
||||
use Intervention\Image\EncodedImage;
|
||||
use Intervention\Image\Encoders\WebpEncoder as GenericWebpEncoder;
|
||||
use Intervention\Image\Interfaces\ImageInterface;
|
||||
use Intervention\Image\Interfaces\SpecializedInterface;
|
||||
|
||||
class WebpEncoder extends GenericWebpEncoder implements SpecializedInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see EncoderInterface::encode()
|
||||
*/
|
||||
public function encode(ImageInterface $image): EncodedImage
|
||||
{
|
||||
$quality = $this->quality === 100 && defined('IMG_WEBP_LOSSLESS') ? IMG_WEBP_LOSSLESS : $this->quality;
|
||||
|
||||
return $this->createEncodedImage(function ($pointer) use ($image, $quality): void {
|
||||
imagewebp($image->core()->native(), $pointer, $quality);
|
||||
}, 'image/webp');
|
||||
}
|
||||
}
|
||||
107
upLoadImage/vendor/intervention/image/src/Drivers/Gd/FontProcessor.php
vendored
Normal file
107
upLoadImage/vendor/intervention/image/src/Drivers/Gd/FontProcessor.php
vendored
Normal file
@@ -0,0 +1,107 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Drivers\Gd;
|
||||
|
||||
use Intervention\Image\Drivers\AbstractFontProcessor;
|
||||
use Intervention\Image\Exceptions\FontException;
|
||||
use Intervention\Image\Geometry\Point;
|
||||
use Intervention\Image\Geometry\Rectangle;
|
||||
use Intervention\Image\Interfaces\FontInterface;
|
||||
use Intervention\Image\Interfaces\SizeInterface;
|
||||
|
||||
class FontProcessor extends AbstractFontProcessor
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see FontProcessorInterface::boxSize()
|
||||
*/
|
||||
public function boxSize(string $text, FontInterface $font): SizeInterface
|
||||
{
|
||||
// if the font has no ttf file the box size is calculated
|
||||
// with gd's internal font system: integer values from 1-5
|
||||
if (!$font->hasFilename()) {
|
||||
// calculate box size from gd font
|
||||
$box = new Rectangle(0, 0);
|
||||
$chars = mb_strlen($text);
|
||||
if ($chars > 0) {
|
||||
$box->setWidth(
|
||||
$chars * $this->gdCharacterWidth((int) $font->filename())
|
||||
);
|
||||
$box->setHeight(
|
||||
$this->gdCharacterHeight((int) $font->filename())
|
||||
);
|
||||
}
|
||||
return $box;
|
||||
}
|
||||
|
||||
// build full path to font file to make sure to pass absolute path to imageftbbox()
|
||||
// because of issues with different GD version behaving differently when passing
|
||||
// relative paths to imageftbbox()
|
||||
$fontPath = realpath($font->filename());
|
||||
if ($fontPath === false) {
|
||||
throw new FontException('Font file ' . $font->filename() . ' does not exist.');
|
||||
}
|
||||
|
||||
// calculate box size from ttf font file with angle 0
|
||||
$box = imageftbbox(
|
||||
size: $this->nativeFontSize($font),
|
||||
angle: 0,
|
||||
font_filename: $fontPath,
|
||||
string: $text,
|
||||
);
|
||||
|
||||
if ($box === false) {
|
||||
throw new FontException('Unable to calculate box size of font ' . $font->filename() . '.');
|
||||
}
|
||||
|
||||
// build size from points
|
||||
return new Rectangle(
|
||||
width: intval(abs($box[6] - $box[4])), // difference of upper-left-x and upper-right-x
|
||||
height: intval(abs($box[7] - $box[1])), // difference if upper-left-y and lower-left-y
|
||||
pivot: new Point($box[6], $box[7]), // position of upper-left corner
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see FontProcessorInterface::nativeFontSize()
|
||||
*/
|
||||
public function nativeFontSize(FontInterface $font): float
|
||||
{
|
||||
return floatval(round($font->size() * .76, 6));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see FontProcessorInterface::leading()
|
||||
*/
|
||||
public function leading(FontInterface $font): int
|
||||
{
|
||||
return (int) round(parent::leading($font) * .8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return width of a single character
|
||||
*/
|
||||
protected function gdCharacterWidth(int $gdfont): int
|
||||
{
|
||||
return $gdfont + 4;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return height of a single character
|
||||
*/
|
||||
protected function gdCharacterHeight(int $gdfont): int
|
||||
{
|
||||
return match ($gdfont) {
|
||||
2, 3 => 14,
|
||||
4, 5 => 16,
|
||||
default => 8,
|
||||
};
|
||||
}
|
||||
}
|
||||
193
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Frame.php
vendored
Normal file
193
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Frame.php
vendored
Normal file
@@ -0,0 +1,193 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Drivers\Gd;
|
||||
|
||||
use GdImage;
|
||||
use Intervention\Image\Drivers\AbstractFrame;
|
||||
use Intervention\Image\Exceptions\ColorException;
|
||||
use Intervention\Image\Exceptions\InputException;
|
||||
use Intervention\Image\Geometry\Rectangle;
|
||||
use Intervention\Image\Image;
|
||||
use Intervention\Image\Interfaces\DriverInterface;
|
||||
use Intervention\Image\Interfaces\FrameInterface;
|
||||
use Intervention\Image\Interfaces\ImageInterface;
|
||||
use Intervention\Image\Interfaces\SizeInterface;
|
||||
|
||||
class Frame extends AbstractFrame implements FrameInterface
|
||||
{
|
||||
/**
|
||||
* Create new frame instance
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(
|
||||
protected GdImage $native,
|
||||
protected float $delay = 0,
|
||||
protected int $dispose = 1,
|
||||
protected int $offset_left = 0,
|
||||
protected int $offset_top = 0
|
||||
) {
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see FrameInterface::toImage()
|
||||
*/
|
||||
public function toImage(DriverInterface $driver): ImageInterface
|
||||
{
|
||||
return new Image($driver, new Core([$this]));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see FrameInterface::setNative()
|
||||
*/
|
||||
public function setNative(mixed $native): FrameInterface
|
||||
{
|
||||
$this->native = $native;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see FrameInterface::native()
|
||||
*/
|
||||
public function native(): GdImage
|
||||
{
|
||||
return $this->native;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see FrameInterface::size()
|
||||
*/
|
||||
public function size(): SizeInterface
|
||||
{
|
||||
return new Rectangle(imagesx($this->native), imagesy($this->native));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see FrameInterface::delay()
|
||||
*/
|
||||
public function delay(): float
|
||||
{
|
||||
return $this->delay;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see FrameInterface::setDelay()
|
||||
*/
|
||||
public function setDelay(float $delay): FrameInterface
|
||||
{
|
||||
$this->delay = $delay;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see FrameInterface::dispose()
|
||||
*/
|
||||
public function dispose(): int
|
||||
{
|
||||
return $this->dispose;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see FrameInterface::setDispose()
|
||||
*
|
||||
* @throws InputException
|
||||
*/
|
||||
public function setDispose(int $dispose): FrameInterface
|
||||
{
|
||||
if (!in_array($dispose, [0, 1, 2, 3])) {
|
||||
throw new InputException('Value for argument $dispose must be 0, 1, 2 or 3.');
|
||||
}
|
||||
|
||||
$this->dispose = $dispose;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see FrameInterface::setOffset()
|
||||
*/
|
||||
public function setOffset(int $left, int $top): FrameInterface
|
||||
{
|
||||
$this->offset_left = $left;
|
||||
$this->offset_top = $top;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see FrameInterface::offsetLeft()
|
||||
*/
|
||||
public function offsetLeft(): int
|
||||
{
|
||||
return $this->offset_left;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see FrameInterface::setOffsetLeft()
|
||||
*/
|
||||
public function setOffsetLeft(int $offset): FrameInterface
|
||||
{
|
||||
$this->offset_left = $offset;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see FrameInterface::offsetTop()
|
||||
*/
|
||||
public function offsetTop(): int
|
||||
{
|
||||
return $this->offset_top;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see FrameInterface::setOffsetTop()
|
||||
*/
|
||||
public function setOffsetTop(int $offset): FrameInterface
|
||||
{
|
||||
$this->offset_top = $offset;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* This workaround helps cloning GdImages which is currently not possible.
|
||||
*
|
||||
* @throws ColorException
|
||||
*/
|
||||
public function __clone(): void
|
||||
{
|
||||
$this->native = Cloner::clone($this->native);
|
||||
}
|
||||
}
|
||||
52
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Modifiers/AlignRotationModifier.php
vendored
Normal file
52
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Modifiers/AlignRotationModifier.php
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Drivers\Gd\Modifiers;
|
||||
|
||||
use Intervention\Image\Interfaces\ImageInterface;
|
||||
use Intervention\Image\Interfaces\SpecializedInterface;
|
||||
use Intervention\Image\Modifiers\AlignRotationModifier as GenericAlignRotationModifier;
|
||||
|
||||
class AlignRotationModifier extends GenericAlignRotationModifier implements SpecializedInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see ModifierInterface::apply()
|
||||
*/
|
||||
public function apply(ImageInterface $image): ImageInterface
|
||||
{
|
||||
$image = match ($image->exif('IFD0.Orientation')) {
|
||||
2 => $image->flop(),
|
||||
3 => $image->rotate(180),
|
||||
4 => $image->rotate(180)->flop(),
|
||||
5 => $image->rotate(270)->flop(),
|
||||
6 => $image->rotate(270),
|
||||
7 => $image->rotate(90)->flop(),
|
||||
8 => $image->rotate(90),
|
||||
default => $image
|
||||
};
|
||||
|
||||
return $this->markAligned($image);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set exif data of image to top-left orientation, marking the image as
|
||||
* aligned and making sure the rotation correction process is not
|
||||
* performed again.
|
||||
*/
|
||||
private function markAligned(ImageInterface $image): ImageInterface
|
||||
{
|
||||
$exif = $image->exif()->map(function ($item) {
|
||||
if (is_array($item) && array_key_exists('Orientation', $item)) {
|
||||
$item['Orientation'] = 1;
|
||||
return $item;
|
||||
}
|
||||
|
||||
return $item;
|
||||
});
|
||||
|
||||
return $image->setExif($exif);
|
||||
}
|
||||
}
|
||||
36
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Modifiers/BlendTransparencyModifier.php
vendored
Normal file
36
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Modifiers/BlendTransparencyModifier.php
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Drivers\Gd\Modifiers;
|
||||
|
||||
use Intervention\Image\Drivers\Gd\Cloner;
|
||||
use Intervention\Image\Interfaces\ImageInterface;
|
||||
use Intervention\Image\Interfaces\SpecializedInterface;
|
||||
use Intervention\Image\Modifiers\BlendTransparencyModifier as GenericBlendTransparencyModifier;
|
||||
|
||||
class BlendTransparencyModifier extends GenericBlendTransparencyModifier implements SpecializedInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see ModifierInterface::apply()
|
||||
*/
|
||||
public function apply(ImageInterface $image): ImageInterface
|
||||
{
|
||||
$blendingColor = $this->blendingColor($this->driver());
|
||||
|
||||
foreach ($image as $frame) {
|
||||
// create new canvas with blending color as background
|
||||
$modified = Cloner::cloneBlended(
|
||||
$frame->native(),
|
||||
background: $blendingColor
|
||||
);
|
||||
|
||||
// set new gd image
|
||||
$frame->setNative($modified);
|
||||
}
|
||||
|
||||
return $image;
|
||||
}
|
||||
}
|
||||
28
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Modifiers/BlurModifier.php
vendored
Normal file
28
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Modifiers/BlurModifier.php
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Drivers\Gd\Modifiers;
|
||||
|
||||
use Intervention\Image\Interfaces\ImageInterface;
|
||||
use Intervention\Image\Interfaces\SpecializedInterface;
|
||||
use Intervention\Image\Modifiers\BlurModifier as GenericBlurModifier;
|
||||
|
||||
class BlurModifier extends GenericBlurModifier implements SpecializedInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see ModifierInterface::apply()
|
||||
*/
|
||||
public function apply(ImageInterface $image): ImageInterface
|
||||
{
|
||||
foreach ($image as $frame) {
|
||||
for ($i = 0; $i < $this->amount; $i++) {
|
||||
imagefilter($frame->native(), IMG_FILTER_GAUSSIAN_BLUR);
|
||||
}
|
||||
}
|
||||
|
||||
return $image;
|
||||
}
|
||||
}
|
||||
26
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Modifiers/BrightnessModifier.php
vendored
Normal file
26
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Modifiers/BrightnessModifier.php
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Drivers\Gd\Modifiers;
|
||||
|
||||
use Intervention\Image\Interfaces\ImageInterface;
|
||||
use Intervention\Image\Interfaces\SpecializedInterface;
|
||||
use Intervention\Image\Modifiers\BrightnessModifier as GenericBrightnessModifier;
|
||||
|
||||
class BrightnessModifier extends GenericBrightnessModifier implements SpecializedInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see ModifierInterface::apply()
|
||||
*/
|
||||
public function apply(ImageInterface $image): ImageInterface
|
||||
{
|
||||
foreach ($image as $frame) {
|
||||
imagefilter($frame->native(), IMG_FILTER_BRIGHTNESS, intval($this->level * 2.55));
|
||||
}
|
||||
|
||||
return $image;
|
||||
}
|
||||
}
|
||||
31
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Modifiers/ColorizeModifier.php
vendored
Normal file
31
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Modifiers/ColorizeModifier.php
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Drivers\Gd\Modifiers;
|
||||
|
||||
use Intervention\Image\Interfaces\ImageInterface;
|
||||
use Intervention\Image\Interfaces\SpecializedInterface;
|
||||
use Intervention\Image\Modifiers\ColorizeModifier as GenericColorizeModifier;
|
||||
|
||||
class ColorizeModifier extends GenericColorizeModifier implements SpecializedInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see ModifierInterface::apply()
|
||||
*/
|
||||
public function apply(ImageInterface $image): ImageInterface
|
||||
{
|
||||
// normalize colorize levels
|
||||
$red = (int) round($this->red * 2.55);
|
||||
$green = (int) round($this->green * 2.55);
|
||||
$blue = (int) round($this->blue * 2.55);
|
||||
|
||||
foreach ($image as $frame) {
|
||||
imagefilter($frame->native(), IMG_FILTER_COLORIZE, $red, $green, $blue);
|
||||
}
|
||||
|
||||
return $image;
|
||||
}
|
||||
}
|
||||
30
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Modifiers/ColorspaceModifier.php
vendored
Normal file
30
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Modifiers/ColorspaceModifier.php
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Drivers\Gd\Modifiers;
|
||||
|
||||
use Intervention\Image\Colors\Rgb\Colorspace as RgbColorspace;
|
||||
use Intervention\Image\Exceptions\NotSupportedException;
|
||||
use Intervention\Image\Interfaces\ImageInterface;
|
||||
use Intervention\Image\Interfaces\SpecializedInterface;
|
||||
use Intervention\Image\Modifiers\ColorspaceModifier as GenericColorspaceModifier;
|
||||
|
||||
class ColorspaceModifier extends GenericColorspaceModifier implements SpecializedInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see ModifierInterface::apply()
|
||||
*/
|
||||
public function apply(ImageInterface $image): ImageInterface
|
||||
{
|
||||
if (!($this->targetColorspace() instanceof RgbColorspace)) {
|
||||
throw new NotSupportedException(
|
||||
'Only RGB colorspace is supported by GD driver.'
|
||||
);
|
||||
}
|
||||
|
||||
return $image;
|
||||
}
|
||||
}
|
||||
93
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Modifiers/ContainModifier.php
vendored
Normal file
93
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Modifiers/ContainModifier.php
vendored
Normal file
@@ -0,0 +1,93 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Drivers\Gd\Modifiers;
|
||||
|
||||
use Intervention\Image\Colors\Rgb\Channels\Blue;
|
||||
use Intervention\Image\Colors\Rgb\Channels\Green;
|
||||
use Intervention\Image\Colors\Rgb\Channels\Red;
|
||||
use Intervention\Image\Drivers\Gd\Cloner;
|
||||
use Intervention\Image\Exceptions\ColorException;
|
||||
use Intervention\Image\Interfaces\ColorInterface;
|
||||
use Intervention\Image\Interfaces\FrameInterface;
|
||||
use Intervention\Image\Interfaces\ImageInterface;
|
||||
use Intervention\Image\Interfaces\SizeInterface;
|
||||
use Intervention\Image\Interfaces\SpecializedInterface;
|
||||
use Intervention\Image\Modifiers\ContainModifier as GenericContainModifier;
|
||||
|
||||
class ContainModifier extends GenericContainModifier implements SpecializedInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see ModifierInterface::apply()
|
||||
*/
|
||||
public function apply(ImageInterface $image): ImageInterface
|
||||
{
|
||||
$crop = $this->getCropSize($image);
|
||||
$resize = $this->getResizeSize($image);
|
||||
$background = $this->driver()->handleInput($this->background);
|
||||
$blendingColor = $this->driver()->handleInput(
|
||||
$this->driver()->config()->blendingColor
|
||||
);
|
||||
|
||||
foreach ($image as $frame) {
|
||||
$this->modify($frame, $crop, $resize, $background, $blendingColor);
|
||||
}
|
||||
|
||||
return $image;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ColorException
|
||||
*/
|
||||
protected function modify(
|
||||
FrameInterface $frame,
|
||||
SizeInterface $crop,
|
||||
SizeInterface $resize,
|
||||
ColorInterface $background,
|
||||
ColorInterface $blendingColor
|
||||
): void {
|
||||
// create new gd image
|
||||
$modified = Cloner::cloneEmpty($frame->native(), $resize, $background);
|
||||
|
||||
// make image area transparent to keep transparency
|
||||
// even if background-color is set
|
||||
$transparent = imagecolorallocatealpha(
|
||||
$modified,
|
||||
$blendingColor->channel(Red::class)->value(),
|
||||
$blendingColor->channel(Green::class)->value(),
|
||||
$blendingColor->channel(Blue::class)->value(),
|
||||
127,
|
||||
);
|
||||
imagealphablending($modified, false); // do not blend / just overwrite
|
||||
imagecolortransparent($modified, $transparent);
|
||||
imagefilledrectangle(
|
||||
$modified,
|
||||
$crop->pivot()->x(),
|
||||
$crop->pivot()->y(),
|
||||
$crop->pivot()->x() + $crop->width() - 1,
|
||||
$crop->pivot()->y() + $crop->height() - 1,
|
||||
$transparent
|
||||
);
|
||||
|
||||
// copy image from original with blending alpha
|
||||
imagealphablending($modified, true);
|
||||
imagecopyresampled(
|
||||
$modified,
|
||||
$frame->native(),
|
||||
$crop->pivot()->x(),
|
||||
$crop->pivot()->y(),
|
||||
0,
|
||||
0,
|
||||
$crop->width(),
|
||||
$crop->height(),
|
||||
$frame->size()->width(),
|
||||
$frame->size()->height()
|
||||
);
|
||||
|
||||
// set new content as resource
|
||||
$frame->setNative($modified);
|
||||
}
|
||||
}
|
||||
26
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Modifiers/ContrastModifier.php
vendored
Normal file
26
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Modifiers/ContrastModifier.php
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Drivers\Gd\Modifiers;
|
||||
|
||||
use Intervention\Image\Interfaces\ImageInterface;
|
||||
use Intervention\Image\Interfaces\SpecializedInterface;
|
||||
use Intervention\Image\Modifiers\ContrastModifier as GenericContrastModifier;
|
||||
|
||||
class ContrastModifier extends GenericContrastModifier implements SpecializedInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see ModifierInterface::apply()
|
||||
*/
|
||||
public function apply(ImageInterface $image): ImageInterface
|
||||
{
|
||||
foreach ($image as $frame) {
|
||||
imagefilter($frame->native(), IMG_FILTER_CONTRAST, ($this->level * -1));
|
||||
}
|
||||
|
||||
return $image;
|
||||
}
|
||||
}
|
||||
19
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Modifiers/CoverDownModifier.php
vendored
Normal file
19
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Modifiers/CoverDownModifier.php
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Drivers\Gd\Modifiers;
|
||||
|
||||
use Intervention\Image\Exceptions\GeometryException;
|
||||
use Intervention\Image\Interfaces\SizeInterface;
|
||||
|
||||
class CoverDownModifier extends CoverModifier
|
||||
{
|
||||
/**
|
||||
* @throws GeometryException
|
||||
*/
|
||||
public function getResizeSize(SizeInterface $size): SizeInterface
|
||||
{
|
||||
return $size->resizeDown($this->width, $this->height);
|
||||
}
|
||||
}
|
||||
59
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Modifiers/CoverModifier.php
vendored
Normal file
59
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Modifiers/CoverModifier.php
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Drivers\Gd\Modifiers;
|
||||
|
||||
use Intervention\Image\Drivers\Gd\Cloner;
|
||||
use Intervention\Image\Exceptions\ColorException;
|
||||
use Intervention\Image\Interfaces\FrameInterface;
|
||||
use Intervention\Image\Interfaces\ImageInterface;
|
||||
use Intervention\Image\Interfaces\SizeInterface;
|
||||
use Intervention\Image\Interfaces\SpecializedInterface;
|
||||
use Intervention\Image\Modifiers\CoverModifier as GenericCoverModifier;
|
||||
|
||||
class CoverModifier extends GenericCoverModifier implements SpecializedInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see ModifierInterface::apply()
|
||||
*/
|
||||
public function apply(ImageInterface $image): ImageInterface
|
||||
{
|
||||
$crop = $this->getCropSize($image);
|
||||
$resize = $this->getResizeSize($crop);
|
||||
|
||||
foreach ($image as $frame) {
|
||||
$this->modifyFrame($frame, $crop, $resize);
|
||||
}
|
||||
|
||||
return $image;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ColorException
|
||||
*/
|
||||
protected function modifyFrame(FrameInterface $frame, SizeInterface $crop, SizeInterface $resize): void
|
||||
{
|
||||
// create new image
|
||||
$modified = Cloner::cloneEmpty($frame->native(), $resize);
|
||||
|
||||
// copy content from resource
|
||||
imagecopyresampled(
|
||||
$modified,
|
||||
$frame->native(),
|
||||
0,
|
||||
0,
|
||||
$crop->pivot()->x(),
|
||||
$crop->pivot()->y(),
|
||||
$resize->width(),
|
||||
$resize->height(),
|
||||
$crop->width(),
|
||||
$crop->height()
|
||||
);
|
||||
|
||||
// set new content as resource
|
||||
$frame->setNative($modified);
|
||||
}
|
||||
}
|
||||
78
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Modifiers/CropModifier.php
vendored
Normal file
78
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Modifiers/CropModifier.php
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Drivers\Gd\Modifiers;
|
||||
|
||||
use Intervention\Image\Drivers\Gd\Cloner;
|
||||
use Intervention\Image\Exceptions\ColorException;
|
||||
use Intervention\Image\Interfaces\ColorInterface;
|
||||
use Intervention\Image\Interfaces\FrameInterface;
|
||||
use Intervention\Image\Interfaces\ImageInterface;
|
||||
use Intervention\Image\Interfaces\SizeInterface;
|
||||
use Intervention\Image\Interfaces\SpecializedInterface;
|
||||
use Intervention\Image\Modifiers\CropModifier as GenericCropModifier;
|
||||
|
||||
class CropModifier extends GenericCropModifier implements SpecializedInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see ModifierInterface::apply()
|
||||
*/
|
||||
public function apply(ImageInterface $image): ImageInterface
|
||||
{
|
||||
$originalSize = $image->size();
|
||||
$crop = $this->crop($image);
|
||||
$background = $this->driver()->handleInput($this->background);
|
||||
|
||||
foreach ($image as $frame) {
|
||||
$this->cropFrame($frame, $originalSize, $crop, $background);
|
||||
}
|
||||
|
||||
return $image;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ColorException
|
||||
*/
|
||||
protected function cropFrame(
|
||||
FrameInterface $frame,
|
||||
SizeInterface $originalSize,
|
||||
SizeInterface $resizeTo,
|
||||
ColorInterface $background
|
||||
): void {
|
||||
// create new image with transparent background
|
||||
$modified = Cloner::cloneEmpty($frame->native(), $resizeTo, $background);
|
||||
|
||||
// define offset
|
||||
$offset_x = $resizeTo->pivot()->x() + $this->offset_x;
|
||||
$offset_y = $resizeTo->pivot()->y() + $this->offset_y;
|
||||
|
||||
// define target width & height
|
||||
$targetWidth = min($resizeTo->width(), $originalSize->width());
|
||||
$targetHeight = min($resizeTo->height(), $originalSize->height());
|
||||
$targetWidth = $targetWidth < $originalSize->width() ? $targetWidth + $offset_x : $targetWidth;
|
||||
$targetHeight = $targetHeight < $originalSize->height() ? $targetHeight + $offset_y : $targetHeight;
|
||||
|
||||
// don't alpha blend for copy operation to keep transparent areas of original image
|
||||
imagealphablending($modified, false);
|
||||
|
||||
// copy content from resource
|
||||
imagecopyresampled(
|
||||
$modified,
|
||||
$frame->native(),
|
||||
$offset_x * -1,
|
||||
$offset_y * -1,
|
||||
0,
|
||||
0,
|
||||
$targetWidth,
|
||||
$targetHeight,
|
||||
$targetWidth,
|
||||
$targetHeight
|
||||
);
|
||||
|
||||
// set new content as resource
|
||||
$frame->setNative($modified);
|
||||
}
|
||||
}
|
||||
234
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Modifiers/DrawBezierModifier.php
vendored
Normal file
234
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Modifiers/DrawBezierModifier.php
vendored
Normal file
@@ -0,0 +1,234 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Drivers\Gd\Modifiers;
|
||||
|
||||
use RuntimeException;
|
||||
use Intervention\Image\Exceptions\GeometryException;
|
||||
use Intervention\Image\Interfaces\ImageInterface;
|
||||
use Intervention\Image\Interfaces\SpecializedInterface;
|
||||
use Intervention\Image\Modifiers\DrawBezierModifier as GenericDrawBezierModifier;
|
||||
|
||||
class DrawBezierModifier extends GenericDrawBezierModifier implements SpecializedInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see ModifierInterface::apply()
|
||||
*
|
||||
* @throws RuntimeException
|
||||
* @throws GeometryException
|
||||
*/
|
||||
public function apply(ImageInterface $image): ImageInterface
|
||||
{
|
||||
foreach ($image as $frame) {
|
||||
if ($this->drawable->count() !== 3 && $this->drawable->count() !== 4) {
|
||||
throw new GeometryException('You must specify either 3 or 4 points to create a bezier curve');
|
||||
}
|
||||
|
||||
[$polygon, $polygon_border_segments] = $this->calculateBezierPoints();
|
||||
|
||||
if ($this->drawable->hasBackgroundColor() || $this->drawable->hasBorder()) {
|
||||
imagealphablending($frame->native(), true);
|
||||
imageantialias($frame->native(), true);
|
||||
}
|
||||
|
||||
if ($this->drawable->hasBackgroundColor()) {
|
||||
$background_color = $this->driver()->colorProcessor($image->colorspace())->colorToNative(
|
||||
$this->backgroundColor()
|
||||
);
|
||||
|
||||
imagesetthickness($frame->native(), 0);
|
||||
imagefilledpolygon(
|
||||
$frame->native(),
|
||||
$polygon,
|
||||
$background_color
|
||||
);
|
||||
}
|
||||
|
||||
if ($this->drawable->hasBorder() && $this->drawable->borderSize() > 0) {
|
||||
$border_color = $this->driver()->colorProcessor($image->colorspace())->colorToNative(
|
||||
$this->borderColor()
|
||||
);
|
||||
|
||||
if ($this->drawable->borderSize() === 1) {
|
||||
imagesetthickness($frame->native(), $this->drawable->borderSize());
|
||||
|
||||
$count = count($polygon);
|
||||
for ($i = 0; $i < $count; $i += 2) {
|
||||
if (array_key_exists($i + 2, $polygon) && array_key_exists($i + 3, $polygon)) {
|
||||
imageline(
|
||||
$frame->native(),
|
||||
$polygon[$i],
|
||||
$polygon[$i + 1],
|
||||
$polygon[$i + 2],
|
||||
$polygon[$i + 3],
|
||||
$border_color
|
||||
);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$polygon_border_segments_total = count($polygon_border_segments);
|
||||
|
||||
for ($i = 0; $i < $polygon_border_segments_total; $i += 1) {
|
||||
imagefilledpolygon(
|
||||
$frame->native(),
|
||||
$polygon_border_segments[$i],
|
||||
$border_color
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $image;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate interpolation points for quadratic beziers using the Bernstein polynomial form
|
||||
*
|
||||
* @return array{'x': float, 'y': float}
|
||||
*/
|
||||
private function calculateQuadraticBezierInterpolationPoint(float $t = 0.05): array
|
||||
{
|
||||
$remainder = 1 - $t;
|
||||
$control_point_1_multiplier = $remainder * $remainder;
|
||||
$control_point_2_multiplier = $remainder * $t * 2;
|
||||
$control_point_3_multiplier = $t * $t;
|
||||
|
||||
$x = (
|
||||
$this->drawable->first()->x() * $control_point_1_multiplier +
|
||||
$this->drawable->second()->x() * $control_point_2_multiplier +
|
||||
$this->drawable->last()->x() * $control_point_3_multiplier
|
||||
);
|
||||
$y = (
|
||||
$this->drawable->first()->y() * $control_point_1_multiplier +
|
||||
$this->drawable->second()->y() * $control_point_2_multiplier +
|
||||
$this->drawable->last()->y() * $control_point_3_multiplier
|
||||
);
|
||||
|
||||
return ['x' => $x, 'y' => $y];
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate interpolation points for cubic beziers using the Bernstein polynomial form
|
||||
*
|
||||
* @return array{'x': float, 'y': float}
|
||||
*/
|
||||
private function calculateCubicBezierInterpolationPoint(float $t = 0.05): array
|
||||
{
|
||||
$remainder = 1 - $t;
|
||||
$t_squared = $t * $t;
|
||||
$remainder_squared = $remainder * $remainder;
|
||||
$control_point_1_multiplier = $remainder_squared * $remainder;
|
||||
$control_point_2_multiplier = $remainder_squared * $t * 3;
|
||||
$control_point_3_multiplier = $t_squared * $remainder * 3;
|
||||
$control_point_4_multiplier = $t_squared * $t;
|
||||
|
||||
$x = (
|
||||
$this->drawable->first()->x() * $control_point_1_multiplier +
|
||||
$this->drawable->second()->x() * $control_point_2_multiplier +
|
||||
$this->drawable->third()->x() * $control_point_3_multiplier +
|
||||
$this->drawable->last()->x() * $control_point_4_multiplier
|
||||
);
|
||||
$y = (
|
||||
$this->drawable->first()->y() * $control_point_1_multiplier +
|
||||
$this->drawable->second()->y() * $control_point_2_multiplier +
|
||||
$this->drawable->third()->y() * $control_point_3_multiplier +
|
||||
$this->drawable->last()->y() * $control_point_4_multiplier
|
||||
);
|
||||
|
||||
return ['x' => $x, 'y' => $y];
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the points needed to draw a quadratic or cubic bezier with optional border/stroke
|
||||
*
|
||||
* @throws GeometryException
|
||||
* @return array{0: array<mixed>, 1: array<mixed>}
|
||||
*/
|
||||
private function calculateBezierPoints(): array
|
||||
{
|
||||
if ($this->drawable->count() !== 3 && $this->drawable->count() !== 4) {
|
||||
throw new GeometryException('You must specify either 3 or 4 points to create a bezier curve');
|
||||
}
|
||||
|
||||
$polygon = [];
|
||||
$inner_polygon = [];
|
||||
$outer_polygon = [];
|
||||
$polygon_border_segments = [];
|
||||
|
||||
// define ratio t; equivalent to 5 percent distance along edge
|
||||
$t = 0.05;
|
||||
|
||||
$polygon[] = $this->drawable->first()->x();
|
||||
$polygon[] = $this->drawable->first()->y();
|
||||
for ($i = $t; $i < 1; $i += $t) {
|
||||
if ($this->drawable->count() === 3) {
|
||||
$ip = $this->calculateQuadraticBezierInterpolationPoint($i);
|
||||
} elseif ($this->drawable->count() === 4) {
|
||||
$ip = $this->calculateCubicBezierInterpolationPoint($i);
|
||||
}
|
||||
$polygon[] = (int) $ip['x'];
|
||||
$polygon[] = (int) $ip['y'];
|
||||
}
|
||||
$polygon[] = $this->drawable->last()->x();
|
||||
$polygon[] = $this->drawable->last()->y();
|
||||
|
||||
if ($this->drawable->hasBorder() && $this->drawable->borderSize() > 1) {
|
||||
// create the border/stroke effect by calculating two new curves with offset positions
|
||||
// from the main polygon and then connecting the inner/outer curves to create separate
|
||||
// 4-point polygon segments
|
||||
$polygon_total_points = count($polygon);
|
||||
$offset = ($this->drawable->borderSize() / 2);
|
||||
|
||||
for ($i = 0; $i < $polygon_total_points; $i += 2) {
|
||||
if (array_key_exists($i + 2, $polygon) && array_key_exists($i + 3, $polygon)) {
|
||||
$dx = $polygon[$i + 2] - $polygon[$i];
|
||||
$dy = $polygon[$i + 3] - $polygon[$i + 1];
|
||||
$dxy_sqrt = ($dx * $dx + $dy * $dy) ** 0.5;
|
||||
|
||||
// inner polygon
|
||||
$scale = $offset / $dxy_sqrt;
|
||||
$ox = -$dy * $scale;
|
||||
$oy = $dx * $scale;
|
||||
|
||||
$inner_polygon[] = $ox + $polygon[$i];
|
||||
$inner_polygon[] = $oy + $polygon[$i + 1];
|
||||
$inner_polygon[] = $ox + $polygon[$i + 2];
|
||||
$inner_polygon[] = $oy + $polygon[$i + 3];
|
||||
|
||||
// outer polygon
|
||||
$scale = -$offset / $dxy_sqrt;
|
||||
$ox = -$dy * $scale;
|
||||
$oy = $dx * $scale;
|
||||
|
||||
$outer_polygon[] = $ox + $polygon[$i];
|
||||
$outer_polygon[] = $oy + $polygon[$i + 1];
|
||||
$outer_polygon[] = $ox + $polygon[$i + 2];
|
||||
$outer_polygon[] = $oy + $polygon[$i + 3];
|
||||
}
|
||||
}
|
||||
|
||||
$inner_polygon_total_points = count($inner_polygon);
|
||||
|
||||
for ($i = 0; $i < $inner_polygon_total_points; $i += 2) {
|
||||
if (array_key_exists($i + 2, $inner_polygon) && array_key_exists($i + 3, $inner_polygon)) {
|
||||
$polygon_border_segments[] = [
|
||||
$inner_polygon[$i],
|
||||
$inner_polygon[$i + 1],
|
||||
$outer_polygon[$i],
|
||||
$outer_polygon[$i + 1],
|
||||
$outer_polygon[$i + 2],
|
||||
$outer_polygon[$i + 3],
|
||||
$inner_polygon[$i + 2],
|
||||
$inner_polygon[$i + 3],
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return [$polygon, $polygon_border_segments];
|
||||
}
|
||||
}
|
||||
78
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Modifiers/DrawEllipseModifier.php
vendored
Normal file
78
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Modifiers/DrawEllipseModifier.php
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Drivers\Gd\Modifiers;
|
||||
|
||||
use RuntimeException;
|
||||
use Intervention\Image\Interfaces\ImageInterface;
|
||||
use Intervention\Image\Interfaces\SpecializedInterface;
|
||||
use Intervention\Image\Modifiers\DrawEllipseModifier as GenericDrawEllipseModifier;
|
||||
|
||||
class DrawEllipseModifier extends GenericDrawEllipseModifier implements SpecializedInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see ModifierInterface::apply()
|
||||
*
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function apply(ImageInterface $image): ImageInterface
|
||||
{
|
||||
foreach ($image as $frame) {
|
||||
if ($this->drawable->hasBorder()) {
|
||||
imagealphablending($frame->native(), true);
|
||||
|
||||
// slightly smaller ellipse to keep 1px bordered edges clean
|
||||
if ($this->drawable->hasBackgroundColor()) {
|
||||
imagefilledellipse(
|
||||
$frame->native(),
|
||||
$this->drawable()->position()->x(),
|
||||
$this->drawable->position()->y(),
|
||||
$this->drawable->width() - 1,
|
||||
$this->drawable->height() - 1,
|
||||
$this->driver()->colorProcessor($image->colorspace())->colorToNative(
|
||||
$this->backgroundColor()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// gd's imageellipse ignores imagesetthickness
|
||||
// so i use imagearc with 360 degrees instead.
|
||||
imagesetthickness(
|
||||
$frame->native(),
|
||||
$this->drawable->borderSize(),
|
||||
);
|
||||
|
||||
imagearc(
|
||||
$frame->native(),
|
||||
$this->drawable()->position()->x(),
|
||||
$this->drawable()->position()->y(),
|
||||
$this->drawable->width(),
|
||||
$this->drawable->height(),
|
||||
0,
|
||||
360,
|
||||
$this->driver()->colorProcessor($image->colorspace())->colorToNative(
|
||||
$this->borderColor()
|
||||
)
|
||||
);
|
||||
} else {
|
||||
imagealphablending($frame->native(), true);
|
||||
imagesetthickness($frame->native(), 0);
|
||||
imagefilledellipse(
|
||||
$frame->native(),
|
||||
$this->drawable()->position()->x(),
|
||||
$this->drawable()->position()->y(),
|
||||
$this->drawable->width(),
|
||||
$this->drawable->height(),
|
||||
$this->driver()->colorProcessor($image->colorspace())->colorToNative(
|
||||
$this->backgroundColor()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $image;
|
||||
}
|
||||
}
|
||||
39
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Modifiers/DrawLineModifier.php
vendored
Normal file
39
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Modifiers/DrawLineModifier.php
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Drivers\Gd\Modifiers;
|
||||
|
||||
use RuntimeException;
|
||||
use Intervention\Image\Interfaces\ImageInterface;
|
||||
use Intervention\Image\Interfaces\SpecializedInterface;
|
||||
use Intervention\Image\Modifiers\DrawLineModifier as GenericDrawLineModifier;
|
||||
|
||||
class DrawLineModifier extends GenericDrawLineModifier implements SpecializedInterface
|
||||
{
|
||||
/**
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function apply(ImageInterface $image): ImageInterface
|
||||
{
|
||||
$color = $this->driver()->colorProcessor($image->colorspace())->colorToNative(
|
||||
$this->backgroundColor()
|
||||
);
|
||||
|
||||
foreach ($image as $frame) {
|
||||
imagealphablending($frame->native(), true);
|
||||
imageantialias($frame->native(), true);
|
||||
imagesetthickness($frame->native(), $this->drawable->width());
|
||||
imageline(
|
||||
$frame->native(),
|
||||
$this->drawable->start()->x(),
|
||||
$this->drawable->start()->y(),
|
||||
$this->drawable->end()->x(),
|
||||
$this->drawable->end()->y(),
|
||||
$color
|
||||
);
|
||||
}
|
||||
|
||||
return $image;
|
||||
}
|
||||
}
|
||||
36
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Modifiers/DrawPixelModifier.php
vendored
Normal file
36
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Modifiers/DrawPixelModifier.php
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Drivers\Gd\Modifiers;
|
||||
|
||||
use Intervention\Image\Interfaces\ImageInterface;
|
||||
use Intervention\Image\Interfaces\SpecializedInterface;
|
||||
use Intervention\Image\Modifiers\DrawPixelModifier as GenericDrawPixelModifier;
|
||||
|
||||
class DrawPixelModifier extends GenericDrawPixelModifier implements SpecializedInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see ModifierInterface::apply()
|
||||
*/
|
||||
public function apply(ImageInterface $image): ImageInterface
|
||||
{
|
||||
$color = $this->driver()->colorProcessor($image->colorspace())->colorToNative(
|
||||
$this->driver()->handleInput($this->color)
|
||||
);
|
||||
|
||||
foreach ($image as $frame) {
|
||||
imagealphablending($frame->native(), true);
|
||||
imagesetpixel(
|
||||
$frame->native(),
|
||||
$this->position->x(),
|
||||
$this->position->y(),
|
||||
$color
|
||||
);
|
||||
}
|
||||
|
||||
return $image;
|
||||
}
|
||||
}
|
||||
51
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Modifiers/DrawPolygonModifier.php
vendored
Normal file
51
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Modifiers/DrawPolygonModifier.php
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Drivers\Gd\Modifiers;
|
||||
|
||||
use RuntimeException;
|
||||
use Intervention\Image\Interfaces\ImageInterface;
|
||||
use Intervention\Image\Interfaces\SpecializedInterface;
|
||||
use Intervention\Image\Modifiers\DrawPolygonModifier as ModifiersDrawPolygonModifier;
|
||||
|
||||
class DrawPolygonModifier extends ModifiersDrawPolygonModifier implements SpecializedInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see ModifierInterface::apply()
|
||||
*
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function apply(ImageInterface $image): ImageInterface
|
||||
{
|
||||
foreach ($image as $frame) {
|
||||
if ($this->drawable->hasBackgroundColor()) {
|
||||
imagealphablending($frame->native(), true);
|
||||
imagesetthickness($frame->native(), 0);
|
||||
imagefilledpolygon(
|
||||
$frame->native(),
|
||||
$this->drawable->toArray(),
|
||||
$this->driver()->colorProcessor($image->colorspace())->colorToNative(
|
||||
$this->backgroundColor()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if ($this->drawable->hasBorder()) {
|
||||
imagealphablending($frame->native(), true);
|
||||
imagesetthickness($frame->native(), $this->drawable->borderSize());
|
||||
imagepolygon(
|
||||
$frame->native(),
|
||||
$this->drawable->toArray(),
|
||||
$this->driver()->colorProcessor($image->colorspace())->colorToNative(
|
||||
$this->borderColor()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $image;
|
||||
}
|
||||
}
|
||||
61
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Modifiers/DrawRectangleModifier.php
vendored
Normal file
61
upLoadImage/vendor/intervention/image/src/Drivers/Gd/Modifiers/DrawRectangleModifier.php
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Intervention\Image\Drivers\Gd\Modifiers;
|
||||
|
||||
use RuntimeException;
|
||||
use Intervention\Image\Interfaces\ImageInterface;
|
||||
use Intervention\Image\Interfaces\SpecializedInterface;
|
||||
use Intervention\Image\Modifiers\DrawRectangleModifier as GenericDrawRectangleModifier;
|
||||
|
||||
class DrawRectangleModifier extends GenericDrawRectangleModifier implements SpecializedInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see ModifierInterface::apply()
|
||||
*
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function apply(ImageInterface $image): ImageInterface
|
||||
{
|
||||
$position = $this->drawable->position();
|
||||
|
||||
foreach ($image as $frame) {
|
||||
// draw background
|
||||
if ($this->drawable->hasBackgroundColor()) {
|
||||
imagealphablending($frame->native(), true);
|
||||
imagesetthickness($frame->native(), 0);
|
||||
imagefilledrectangle(
|
||||
$frame->native(),
|
||||
$position->x(),
|
||||
$position->y(),
|
||||
$position->x() + $this->drawable->width(),
|
||||
$position->y() + $this->drawable->height(),
|
||||
$this->driver()->colorProcessor($image->colorspace())->colorToNative(
|
||||
$this->backgroundColor()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// draw border
|
||||
if ($this->drawable->hasBorder()) {
|
||||
imagealphablending($frame->native(), true);
|
||||
imagesetthickness($frame->native(), $this->drawable->borderSize());
|
||||
imagerectangle(
|
||||
$frame->native(),
|
||||
$position->x(),
|
||||
$position->y(),
|
||||
$position->x() + $this->drawable->width(),
|
||||
$position->y() + $this->drawable->height(),
|
||||
$this->driver()->colorProcessor($image->colorspace())->colorToNative(
|
||||
$this->borderColor()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $image;
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user