mirror of
https://github.com/Intervention/image.git
synced 2025-09-02 18:32:56 +02:00
Add Analyzers
This commit is contained in:
14
src/Analyzers/AbstractAnalyzer.php
Normal file
14
src/Analyzers/AbstractAnalyzer.php
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Intervention\Image\Analyzers;
|
||||||
|
|
||||||
|
use Intervention\Image\Interfaces\AnalyzerInterface;
|
||||||
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
|
|
||||||
|
abstract class AbstractAnalyzer implements AnalyzerInterface
|
||||||
|
{
|
||||||
|
public function analyze(ImageInterface $image): mixed
|
||||||
|
{
|
||||||
|
return $image->analyze($this);
|
||||||
|
}
|
||||||
|
}
|
7
src/Analyzers/ColorspaceAnalyzer.php
Normal file
7
src/Analyzers/ColorspaceAnalyzer.php
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Intervention\Image\Analyzers;
|
||||||
|
|
||||||
|
class ColorspaceAnalyzer extends AbstractAnalyzer
|
||||||
|
{
|
||||||
|
}
|
7
src/Analyzers/HeightAnalyzer.php
Normal file
7
src/Analyzers/HeightAnalyzer.php
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Intervention\Image\Analyzers;
|
||||||
|
|
||||||
|
class HeightAnalyzer extends AbstractAnalyzer
|
||||||
|
{
|
||||||
|
}
|
13
src/Analyzers/PixelColorAnalyzer.php
Normal file
13
src/Analyzers/PixelColorAnalyzer.php
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Intervention\Image\Analyzers;
|
||||||
|
|
||||||
|
class PixelColorAnalyzer extends AbstractAnalyzer
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
public int $x,
|
||||||
|
public int $y,
|
||||||
|
public int $frame_key = 0
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
}
|
12
src/Analyzers/PixelColorsAnalyzer.php
Normal file
12
src/Analyzers/PixelColorsAnalyzer.php
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Intervention\Image\Analyzers;
|
||||||
|
|
||||||
|
class PixelColorsAnalyzer extends AbstractAnalyzer
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
public int $x,
|
||||||
|
public int $y
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
}
|
7
src/Analyzers/ProfileAnalyzer.php
Normal file
7
src/Analyzers/ProfileAnalyzer.php
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Intervention\Image\Analyzers;
|
||||||
|
|
||||||
|
class ProfileAnalyzer extends AbstractAnalyzer
|
||||||
|
{
|
||||||
|
}
|
7
src/Analyzers/ResolutionAnalyzer.php
Normal file
7
src/Analyzers/ResolutionAnalyzer.php
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Intervention\Image\Analyzers;
|
||||||
|
|
||||||
|
class ResolutionAnalyzer extends AbstractAnalyzer
|
||||||
|
{
|
||||||
|
}
|
7
src/Analyzers/WidthAnalyzer.php
Normal file
7
src/Analyzers/WidthAnalyzer.php
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Intervention\Image\Analyzers;
|
||||||
|
|
||||||
|
class WidthAnalyzer extends AbstractAnalyzer
|
||||||
|
{
|
||||||
|
}
|
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace Intervention\Image\Drivers;
|
namespace Intervention\Image\Drivers;
|
||||||
|
|
||||||
|
use Intervention\Image\Exceptions\MissingDriverComponentException;
|
||||||
use Intervention\Image\Interfaces\DriverInterface;
|
use Intervention\Image\Interfaces\DriverInterface;
|
||||||
use ReflectionClass;
|
use ReflectionClass;
|
||||||
|
|
||||||
@@ -17,6 +18,7 @@ abstract class AbstractDriver implements DriverInterface
|
|||||||
$department = match ($department) {
|
$department = match ($department) {
|
||||||
'Modifier', 'Writer' => 'Modifiers',
|
'Modifier', 'Writer' => 'Modifiers',
|
||||||
'Encoder' => 'Encoders',
|
'Encoder' => 'Encoders',
|
||||||
|
'Analyzer' => 'Analyzers',
|
||||||
default => null,
|
default => null,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -28,6 +30,12 @@ abstract class AbstractDriver implements DriverInterface
|
|||||||
return !empty($dept);
|
return !empty($dept);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
if (! class_exists($specialized)) {
|
||||||
|
throw new MissingDriverComponentException(
|
||||||
|
$classname . " is not supported by " . $this->id() . " driver."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return new $specialized($input, $this);
|
return new $specialized($input, $this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
31
src/Drivers/DriverAnalyzer.php
Normal file
31
src/Drivers/DriverAnalyzer.php
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Intervention\Image\Drivers;
|
||||||
|
|
||||||
|
use Intervention\Image\Interfaces\AnalyzerInterface;
|
||||||
|
use Intervention\Image\Interfaces\DriverInterface;
|
||||||
|
|
||||||
|
abstract class DriverAnalyzer implements AnalyzerInterface
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
protected AnalyzerInterface $analyzer,
|
||||||
|
protected DriverInterface $driver
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public function driver(): DriverInterface
|
||||||
|
{
|
||||||
|
return $this->driver;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Magic method to read attributes of underlying analyzer
|
||||||
|
*
|
||||||
|
* @param string $name
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function __get(string $name): mixed
|
||||||
|
{
|
||||||
|
return $this->analyzer->$name;
|
||||||
|
}
|
||||||
|
}
|
15
src/Drivers/Gd/Analyzers/ColorspaceAnalyzer.php
Normal file
15
src/Drivers/Gd/Analyzers/ColorspaceAnalyzer.php
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Intervention\Image\Drivers\Gd\Analyzers;
|
||||||
|
|
||||||
|
use Intervention\Image\Colors\Rgb\Colorspace;
|
||||||
|
use Intervention\Image\Drivers\DriverAnalyzer;
|
||||||
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
|
|
||||||
|
class ColorspaceAnalyzer extends DriverAnalyzer
|
||||||
|
{
|
||||||
|
public function analyze(ImageInterface $image): mixed
|
||||||
|
{
|
||||||
|
return new Colorspace();
|
||||||
|
}
|
||||||
|
}
|
14
src/Drivers/Gd/Analyzers/HeightAnalyzer.php
Normal file
14
src/Drivers/Gd/Analyzers/HeightAnalyzer.php
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Intervention\Image\Drivers\Gd\Analyzers;
|
||||||
|
|
||||||
|
use Intervention\Image\Drivers\DriverAnalyzer;
|
||||||
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
|
|
||||||
|
class HeightAnalyzer extends DriverAnalyzer
|
||||||
|
{
|
||||||
|
public function analyze(ImageInterface $image): mixed
|
||||||
|
{
|
||||||
|
return imagesy($image->core()->native());
|
||||||
|
}
|
||||||
|
}
|
34
src/Drivers/Gd/Analyzers/PixelColorAnalyzer.php
Normal file
34
src/Drivers/Gd/Analyzers/PixelColorAnalyzer.php
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Intervention\Image\Drivers\Gd\Analyzers;
|
||||||
|
|
||||||
|
use GdImage;
|
||||||
|
use Intervention\Image\Drivers\DriverAnalyzer;
|
||||||
|
use Intervention\Image\Exceptions\GeometryException;
|
||||||
|
use Intervention\Image\Interfaces\ColorInterface;
|
||||||
|
use Intervention\Image\Interfaces\ColorspaceInterface;
|
||||||
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
|
|
||||||
|
class PixelColorAnalyzer extends DriverAnalyzer
|
||||||
|
{
|
||||||
|
public function analyze(ImageInterface $image): mixed
|
||||||
|
{
|
||||||
|
return $this->colorAt(
|
||||||
|
$image->colorspace(),
|
||||||
|
$image->core()->frame($this->frame_key)->native()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function colorAt(ColorspaceInterface $colorspace, GdImage $gd): ColorInterface
|
||||||
|
{
|
||||||
|
$index = @imagecolorat($gd, $this->x, $this->y);
|
||||||
|
|
||||||
|
if ($index === false) {
|
||||||
|
throw new GeometryException(
|
||||||
|
'The specified position is not in the valid image area.'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->driver()->colorProcessor($colorspace)->nativeToColor($index);
|
||||||
|
}
|
||||||
|
}
|
23
src/Drivers/Gd/Analyzers/PixelColorsAnalyzer.php
Normal file
23
src/Drivers/Gd/Analyzers/PixelColorsAnalyzer.php
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Intervention\Image\Drivers\Gd\Analyzers;
|
||||||
|
|
||||||
|
use Intervention\Image\Collection;
|
||||||
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
|
|
||||||
|
class PixelColorsAnalyzer extends PixelColorAnalyzer
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
15
src/Drivers/Gd/Analyzers/ResolutionAnalyzer.php
Normal file
15
src/Drivers/Gd/Analyzers/ResolutionAnalyzer.php
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Intervention\Image\Drivers\Gd\Analyzers;
|
||||||
|
|
||||||
|
use Intervention\Image\Drivers\DriverAnalyzer;
|
||||||
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
|
use Intervention\Image\Resolution;
|
||||||
|
|
||||||
|
class ResolutionAnalyzer extends DriverAnalyzer
|
||||||
|
{
|
||||||
|
public function analyze(ImageInterface $image): mixed
|
||||||
|
{
|
||||||
|
return new Resolution(...imageresolution($image->core()->native()));
|
||||||
|
}
|
||||||
|
}
|
14
src/Drivers/Gd/Analyzers/WidthAnalyzer.php
Normal file
14
src/Drivers/Gd/Analyzers/WidthAnalyzer.php
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Intervention\Image\Drivers\Gd\Analyzers;
|
||||||
|
|
||||||
|
use Intervention\Image\Drivers\DriverAnalyzer;
|
||||||
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
|
|
||||||
|
class WidthAnalyzer extends DriverAnalyzer
|
||||||
|
{
|
||||||
|
public function analyze(ImageInterface $image): mixed
|
||||||
|
{
|
||||||
|
return imagesx($image->core()->native());
|
||||||
|
}
|
||||||
|
}
|
@@ -6,7 +6,9 @@ use Intervention\Image\Colors\Rgb\Channels\Alpha;
|
|||||||
use Intervention\Image\Colors\Rgb\Channels\Blue;
|
use Intervention\Image\Colors\Rgb\Channels\Blue;
|
||||||
use Intervention\Image\Colors\Rgb\Channels\Green;
|
use Intervention\Image\Colors\Rgb\Channels\Green;
|
||||||
use Intervention\Image\Colors\Rgb\Channels\Red;
|
use Intervention\Image\Colors\Rgb\Channels\Red;
|
||||||
|
use Intervention\Image\Colors\Rgb\Color;
|
||||||
use Intervention\Image\Colors\Rgb\Colorspace;
|
use Intervention\Image\Colors\Rgb\Colorspace;
|
||||||
|
use Intervention\Image\Exceptions\ColorException;
|
||||||
use Intervention\Image\Interfaces\ColorInterface;
|
use Intervention\Image\Interfaces\ColorInterface;
|
||||||
use Intervention\Image\Interfaces\ColorProcessorInterface;
|
use Intervention\Image\Interfaces\ColorProcessorInterface;
|
||||||
use Intervention\Image\Interfaces\ColorspaceInterface;
|
use Intervention\Image\Interfaces\ColorspaceInterface;
|
||||||
@@ -31,6 +33,24 @@ class ColorProcessor implements ColorProcessorInterface
|
|||||||
return ($a << 24) + ($r << 16) + ($g << 8) + $b;
|
return ($a << 24) + ($r << 16) + ($g << 8) + $b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function nativeToColor(mixed $value): ColorInterface
|
||||||
|
{
|
||||||
|
if (! is_int($value)) {
|
||||||
|
throw new ColorException("GD driver can only decode colors in integer format.");
|
||||||
|
}
|
||||||
|
|
||||||
|
$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
|
* Convert input in range (min) to (max) to the corresponding value
|
||||||
* in target range (targetMin) to (targetMax).
|
* in target range (targetMin) to (targetMax).
|
||||||
|
@@ -3,8 +3,6 @@
|
|||||||
namespace Intervention\Image\Drivers\Gd;
|
namespace Intervention\Image\Drivers\Gd;
|
||||||
|
|
||||||
use Intervention\Image\Collection;
|
use Intervention\Image\Collection;
|
||||||
use Intervention\Image\Colors\Rgb\Colorspace as RgbColorspace;
|
|
||||||
use Intervention\Image\Interfaces\ColorspaceInterface;
|
|
||||||
use Intervention\Image\Interfaces\CoreInterface;
|
use Intervention\Image\Interfaces\CoreInterface;
|
||||||
use Intervention\Image\Interfaces\FrameInterface;
|
use Intervention\Image\Interfaces\FrameInterface;
|
||||||
|
|
||||||
@@ -17,16 +15,6 @@ class Core extends Collection implements CoreInterface
|
|||||||
return $this->first()->native();
|
return $this->first()->native();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function width(): int
|
|
||||||
{
|
|
||||||
return imagesx($this->native());
|
|
||||||
}
|
|
||||||
|
|
||||||
public function height(): int
|
|
||||||
{
|
|
||||||
return imagesy($this->native());
|
|
||||||
}
|
|
||||||
|
|
||||||
public function frame(int $position): FrameInterface
|
public function frame(int $position): FrameInterface
|
||||||
{
|
{
|
||||||
return $this->getAtPosition($position);
|
return $this->getAtPosition($position);
|
||||||
@@ -43,9 +31,4 @@ class Core extends Collection implements CoreInterface
|
|||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function colorspace(): ColorspaceInterface
|
|
||||||
{
|
|
||||||
return new RgbColorspace();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -5,11 +5,17 @@ namespace Intervention\Image\Drivers\Gd;
|
|||||||
use Intervention\Image\Drivers\AbstractDriver;
|
use Intervention\Image\Drivers\AbstractDriver;
|
||||||
use Intervention\Image\Image;
|
use Intervention\Image\Image;
|
||||||
use Intervention\Image\Interfaces\ColorInterface;
|
use Intervention\Image\Interfaces\ColorInterface;
|
||||||
|
use Intervention\Image\Interfaces\ColorProcessorInterface;
|
||||||
use Intervention\Image\Interfaces\ColorspaceInterface;
|
use Intervention\Image\Interfaces\ColorspaceInterface;
|
||||||
use Intervention\Image\Interfaces\ImageInterface;
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
|
|
||||||
class Driver extends AbstractDriver
|
class Driver extends AbstractDriver
|
||||||
{
|
{
|
||||||
|
public function id(): string
|
||||||
|
{
|
||||||
|
return 'GD';
|
||||||
|
}
|
||||||
|
|
||||||
public function createImage(int $width, int $height): ImageInterface
|
public function createImage(int $width, int $height): ImageInterface
|
||||||
{
|
{
|
||||||
// build new transparent GDImage
|
// build new transparent GDImage
|
||||||
@@ -33,6 +39,11 @@ class Driver extends AbstractDriver
|
|||||||
return (new InputHandler())->handle($input);
|
return (new InputHandler())->handle($input);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function colorProcessor(ColorspaceInterface $colorspace): ColorProcessorInterface
|
||||||
|
{
|
||||||
|
return new ColorProcessor($colorspace);
|
||||||
|
}
|
||||||
|
|
||||||
public function colorToNative(ColorInterface $color, ColorspaceInterface $colorspace): mixed
|
public function colorToNative(ColorInterface $color, ColorspaceInterface $colorspace): mixed
|
||||||
{
|
{
|
||||||
return (new ColorProcessor($colorspace))->colorToNative($color);
|
return (new ColorProcessor($colorspace))->colorToNative($color);
|
||||||
|
20
src/Drivers/Imagick/Analyzers/ColorspaceAnalyzer.php
Normal file
20
src/Drivers/Imagick/Analyzers/ColorspaceAnalyzer.php
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Intervention\Image\Drivers\Imagick\Analyzers;
|
||||||
|
|
||||||
|
use Imagick;
|
||||||
|
use Intervention\Image\Drivers\DriverAnalyzer;
|
||||||
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
|
use Intervention\Image\Colors\Cmyk\Colorspace as CmykColorspace;
|
||||||
|
use Intervention\Image\Colors\Rgb\Colorspace as RgbColorspace;
|
||||||
|
|
||||||
|
class ColorspaceAnalyzer extends DriverAnalyzer
|
||||||
|
{
|
||||||
|
public function analyze(ImageInterface $image): mixed
|
||||||
|
{
|
||||||
|
return match ($image->core()->native()->getImageColorspace()) {
|
||||||
|
Imagick::COLORSPACE_CMYK => new CmykColorspace(),
|
||||||
|
default => new RgbColorspace(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
14
src/Drivers/Imagick/Analyzers/HeightAnalyzer.php
Normal file
14
src/Drivers/Imagick/Analyzers/HeightAnalyzer.php
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Intervention\Image\Drivers\Imagick\Analyzers;
|
||||||
|
|
||||||
|
use Intervention\Image\Drivers\DriverAnalyzer;
|
||||||
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
|
|
||||||
|
class HeightAnalyzer extends DriverAnalyzer
|
||||||
|
{
|
||||||
|
public function analyze(ImageInterface $image): mixed
|
||||||
|
{
|
||||||
|
return $image->core()->native()->getImageHeight();
|
||||||
|
}
|
||||||
|
}
|
29
src/Drivers/Imagick/Analyzers/PixelColorAnalyzer.php
Normal file
29
src/Drivers/Imagick/Analyzers/PixelColorAnalyzer.php
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Intervention\Image\Drivers\Imagick\Analyzers;
|
||||||
|
|
||||||
|
use Imagick;
|
||||||
|
use Intervention\Image\Drivers\DriverAnalyzer;
|
||||||
|
use Intervention\Image\Interfaces\ColorInterface;
|
||||||
|
use Intervention\Image\Interfaces\ColorspaceInterface;
|
||||||
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
|
|
||||||
|
class PixelColorAnalyzer extends DriverAnalyzer
|
||||||
|
{
|
||||||
|
public function analyze(ImageInterface $image): mixed
|
||||||
|
{
|
||||||
|
return $this->colorAt(
|
||||||
|
$image->colorspace(),
|
||||||
|
$image->core()->frame($this->frame_key)->native()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function colorAt(ColorspaceInterface $colorspace, Imagick $imagick): ColorInterface
|
||||||
|
{
|
||||||
|
return $this->driver()
|
||||||
|
->colorProcessor($colorspace)
|
||||||
|
->nativeToColor(
|
||||||
|
$imagick->getImagePixelColor($this->x, $this->x)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
23
src/Drivers/Imagick/Analyzers/PixelColorsAnalyzer.php
Normal file
23
src/Drivers/Imagick/Analyzers/PixelColorsAnalyzer.php
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Intervention\Image\Drivers\Imagick\Analyzers;
|
||||||
|
|
||||||
|
use Intervention\Image\Collection;
|
||||||
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
|
|
||||||
|
class PixelColorsAnalyzer extends PixelColorAnalyzer
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
22
src/Drivers/Imagick/Analyzers/ProfileAnalyzer.php
Normal file
22
src/Drivers/Imagick/Analyzers/ProfileAnalyzer.php
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Intervention\Image\Drivers\Imagick\Analyzers;
|
||||||
|
|
||||||
|
use Intervention\Image\Colors\Profile;
|
||||||
|
use Intervention\Image\Drivers\DriverAnalyzer;
|
||||||
|
use Intervention\Image\Exceptions\ColorException;
|
||||||
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
|
|
||||||
|
class ProfileAnalyzer extends DriverAnalyzer
|
||||||
|
{
|
||||||
|
public function analyze(ImageInterface $image): mixed
|
||||||
|
{
|
||||||
|
$profiles = $image->core()->native()->getImageProfiles('icc');
|
||||||
|
|
||||||
|
if (!array_key_exists('icc', $profiles)) {
|
||||||
|
throw new ColorException('No ICC profile found in image.');
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Profile($profiles['icc']);
|
||||||
|
}
|
||||||
|
}
|
15
src/Drivers/Imagick/Analyzers/ResolutionAnalyzer.php
Normal file
15
src/Drivers/Imagick/Analyzers/ResolutionAnalyzer.php
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Intervention\Image\Drivers\Imagick\Analyzers;
|
||||||
|
|
||||||
|
use Intervention\Image\Drivers\DriverAnalyzer;
|
||||||
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
|
use Intervention\Image\Resolution;
|
||||||
|
|
||||||
|
class ResolutionAnalyzer extends DriverAnalyzer
|
||||||
|
{
|
||||||
|
public function analyze(ImageInterface $image): mixed
|
||||||
|
{
|
||||||
|
return new Resolution(...$image->core()->native()->getImageResolution());
|
||||||
|
}
|
||||||
|
}
|
14
src/Drivers/Imagick/Analyzers/WidthAnalyzer.php
Normal file
14
src/Drivers/Imagick/Analyzers/WidthAnalyzer.php
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Intervention\Image\Drivers\Imagick\Analyzers;
|
||||||
|
|
||||||
|
use Intervention\Image\Drivers\DriverAnalyzer;
|
||||||
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
|
|
||||||
|
class WidthAnalyzer extends DriverAnalyzer
|
||||||
|
{
|
||||||
|
public function analyze(ImageInterface $image): mixed
|
||||||
|
{
|
||||||
|
return $image->core()->native()->getImageWidth();
|
||||||
|
}
|
||||||
|
}
|
@@ -2,7 +2,9 @@
|
|||||||
|
|
||||||
namespace Intervention\Image\Drivers\Imagick;
|
namespace Intervention\Image\Drivers\Imagick;
|
||||||
|
|
||||||
|
use Imagick;
|
||||||
use ImagickPixel;
|
use ImagickPixel;
|
||||||
|
use Intervention\Image\Colors\Cmyk\Colorspace as CmykColorspace;
|
||||||
use Intervention\Image\Interfaces\ColorInterface;
|
use Intervention\Image\Interfaces\ColorInterface;
|
||||||
use Intervention\Image\Interfaces\ColorProcessorInterface;
|
use Intervention\Image\Interfaces\ColorProcessorInterface;
|
||||||
use Intervention\Image\Interfaces\ColorspaceInterface;
|
use Intervention\Image\Interfaces\ColorspaceInterface;
|
||||||
@@ -19,4 +21,22 @@ class ColorProcessor implements ColorProcessorInterface
|
|||||||
(string) $color->convertTo($this->colorspace)
|
(string) $color->convertTo($this->colorspace)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function nativeToColor(mixed $native): ColorInterface
|
||||||
|
{
|
||||||
|
return match (get_class($this->colorspace)) {
|
||||||
|
CmykColorspace::class => $this->colorspace->colorFromNormalized([
|
||||||
|
$native->getColorValue(Imagick::COLOR_CYAN),
|
||||||
|
$native->getColorValue(Imagick::COLOR_MAGENTA),
|
||||||
|
$native->getColorValue(Imagick::COLOR_YELLOW),
|
||||||
|
$native->getColorValue(Imagick::COLOR_BLACK),
|
||||||
|
]),
|
||||||
|
default => $this->colorspace->colorFromNormalized([
|
||||||
|
$native->getColorValue(Imagick::COLOR_RED),
|
||||||
|
$native->getColorValue(Imagick::COLOR_GREEN),
|
||||||
|
$native->getColorValue(Imagick::COLOR_BLUE),
|
||||||
|
$native->getColorValue(Imagick::COLOR_ALPHA),
|
||||||
|
]),
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -5,10 +5,7 @@ namespace Intervention\Image\Drivers\Imagick;
|
|||||||
use Imagick;
|
use Imagick;
|
||||||
use ImagickException;
|
use ImagickException;
|
||||||
use Iterator;
|
use Iterator;
|
||||||
use Intervention\Image\Interfaces\ColorspaceInterface;
|
|
||||||
use Intervention\Image\Interfaces\CoreInterface;
|
use Intervention\Image\Interfaces\CoreInterface;
|
||||||
use Intervention\Image\Colors\Cmyk\Colorspace as CmykColorspace;
|
|
||||||
use Intervention\Image\Colors\Rgb\Colorspace as RgbColorspace;
|
|
||||||
use Intervention\Image\Exceptions\AnimationException;
|
use Intervention\Image\Exceptions\AnimationException;
|
||||||
use Intervention\Image\Interfaces\FrameInterface;
|
use Intervention\Image\Interfaces\FrameInterface;
|
||||||
|
|
||||||
@@ -63,16 +60,6 @@ class Core implements CoreInterface, Iterator
|
|||||||
return $this->imagick;
|
return $this->imagick;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function width(): int
|
|
||||||
{
|
|
||||||
return $this->imagick->getImageWidth();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function height(): int
|
|
||||||
{
|
|
||||||
return $this->imagick->getImageHeight();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function frame(int $position): FrameInterface
|
public function frame(int $position): FrameInterface
|
||||||
{
|
{
|
||||||
foreach ($this->imagick as $core) {
|
foreach ($this->imagick as $core) {
|
||||||
@@ -96,12 +83,4 @@ class Core implements CoreInterface, Iterator
|
|||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function colorspace(): ColorspaceInterface
|
|
||||||
{
|
|
||||||
return match ($this->imagick->getImageColorspace()) {
|
|
||||||
Imagick::COLORSPACE_CMYK => new CmykColorspace(),
|
|
||||||
default => new RgbColorspace(),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -7,11 +7,17 @@ use ImagickPixel;
|
|||||||
use Intervention\Image\Drivers\AbstractDriver;
|
use Intervention\Image\Drivers\AbstractDriver;
|
||||||
use Intervention\Image\Image;
|
use Intervention\Image\Image;
|
||||||
use Intervention\Image\Interfaces\ColorInterface;
|
use Intervention\Image\Interfaces\ColorInterface;
|
||||||
|
use Intervention\Image\Interfaces\ColorProcessorInterface;
|
||||||
use Intervention\Image\Interfaces\ColorspaceInterface;
|
use Intervention\Image\Interfaces\ColorspaceInterface;
|
||||||
use Intervention\Image\Interfaces\ImageInterface;
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
|
|
||||||
class Driver extends AbstractDriver
|
class Driver extends AbstractDriver
|
||||||
{
|
{
|
||||||
|
public function id(): string
|
||||||
|
{
|
||||||
|
return 'Imagick';
|
||||||
|
}
|
||||||
|
|
||||||
public function createImage(int $width, int $height): ImageInterface
|
public function createImage(int $width, int $height): ImageInterface
|
||||||
{
|
{
|
||||||
$background = new ImagickPixel('rgba(0, 0, 0, 0)');
|
$background = new ImagickPixel('rgba(0, 0, 0, 0)');
|
||||||
@@ -31,6 +37,11 @@ class Driver extends AbstractDriver
|
|||||||
return (new InputHandler())->handle($input);
|
return (new InputHandler())->handle($input);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function colorProcessor(ColorspaceInterface $colorspace): ColorProcessorInterface
|
||||||
|
{
|
||||||
|
return new ColorProcessor($colorspace);
|
||||||
|
}
|
||||||
|
|
||||||
public function colorToNative(ColorInterface $color, ColorspaceInterface $colorspace): mixed
|
public function colorToNative(ColorInterface $color, ColorspaceInterface $colorspace): mixed
|
||||||
{
|
{
|
||||||
return (new ColorProcessor($colorspace))->colorToNative($color);
|
return (new ColorProcessor($colorspace))->colorToNative($color);
|
||||||
|
@@ -10,7 +10,7 @@ class SharpenModifier extends DriverModifier
|
|||||||
public function apply(ImageInterface $image): ImageInterface
|
public function apply(ImageInterface $image): ImageInterface
|
||||||
{
|
{
|
||||||
foreach ($image as $frame) {
|
foreach ($image as $frame) {
|
||||||
$frame->data()->unsharpMaskImage(1, 1, $this->amount / 6.25, 0);
|
$frame->native()->unsharpMaskImage(1, 1, $this->amount / 6.25, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $image;
|
return $image;
|
||||||
|
@@ -3,16 +3,28 @@
|
|||||||
namespace Intervention\Image;
|
namespace Intervention\Image;
|
||||||
|
|
||||||
use Countable;
|
use Countable;
|
||||||
|
use Intervention\Image\Analyzers\ColorspaceAnalyzer;
|
||||||
|
use Intervention\Image\Analyzers\HeightAnalyzer;
|
||||||
|
use Intervention\Image\Analyzers\PixelColorAnalyzer;
|
||||||
|
use Intervention\Image\Analyzers\PixelColorsAnalyzer;
|
||||||
|
use Intervention\Image\Analyzers\ProfileAnalyzer;
|
||||||
|
use Intervention\Image\Analyzers\ResolutionAnalyzer;
|
||||||
|
use Intervention\Image\Analyzers\WidthAnalyzer;
|
||||||
use Traversable;
|
use Traversable;
|
||||||
use Intervention\Image\Geometry\Rectangle;
|
use Intervention\Image\Geometry\Rectangle;
|
||||||
|
use Intervention\Image\Interfaces\AnalyzerInterface;
|
||||||
use Intervention\Image\Interfaces\CollectionInterface;
|
use Intervention\Image\Interfaces\CollectionInterface;
|
||||||
|
use Intervention\Image\Interfaces\ColorInterface;
|
||||||
use Intervention\Image\Interfaces\ColorspaceInterface;
|
use Intervention\Image\Interfaces\ColorspaceInterface;
|
||||||
use Intervention\Image\Interfaces\CoreInterface;
|
use Intervention\Image\Interfaces\CoreInterface;
|
||||||
use Intervention\Image\Interfaces\DriverInterface;
|
use Intervention\Image\Interfaces\DriverInterface;
|
||||||
use Intervention\Image\Interfaces\EncoderInterface;
|
use Intervention\Image\Interfaces\EncoderInterface;
|
||||||
use Intervention\Image\Interfaces\ImageInterface;
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
use Intervention\Image\Interfaces\ModifierInterface;
|
use Intervention\Image\Interfaces\ModifierInterface;
|
||||||
|
use Intervention\Image\Interfaces\ProfileInterface;
|
||||||
|
use Intervention\Image\Interfaces\ResolutionInterface;
|
||||||
use Intervention\Image\Interfaces\SizeInterface;
|
use Intervention\Image\Interfaces\SizeInterface;
|
||||||
|
use Intervention\Image\Modifiers\SharpenModifier;
|
||||||
|
|
||||||
class Image implements ImageInterface, Countable
|
class Image implements ImageInterface, Countable
|
||||||
{
|
{
|
||||||
@@ -33,21 +45,6 @@ class Image implements ImageInterface, Countable
|
|||||||
return $this->core;
|
return $this->core;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function width(): int
|
|
||||||
{
|
|
||||||
return $this->core->width();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function height(): int
|
|
||||||
{
|
|
||||||
return $this->core->height();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function size(): SizeInterface
|
|
||||||
{
|
|
||||||
return new Rectangle($this->width(), $this->height());
|
|
||||||
}
|
|
||||||
|
|
||||||
public function count(): int
|
public function count(): int
|
||||||
{
|
{
|
||||||
return $this->core->count();
|
return $this->core->count();
|
||||||
@@ -68,11 +65,6 @@ class Image implements ImageInterface, Countable
|
|||||||
return $this->core->loops();
|
return $this->core->loops();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function colorspace(): ColorspaceInterface
|
|
||||||
{
|
|
||||||
return $this->core->colorspace();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function exif(?string $query = null): mixed
|
public function exif(?string $query = null): mixed
|
||||||
{
|
{
|
||||||
return is_null($query) ? $this->exif : $this->exif->get($query);
|
return is_null($query) ? $this->exif : $this->exif->get($query);
|
||||||
@@ -83,8 +75,58 @@ class Image implements ImageInterface, Countable
|
|||||||
return $this->driver->resolve($modifier)->apply($this);
|
return $this->driver->resolve($modifier)->apply($this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function analyze(AnalyzerInterface $analyzer): mixed
|
||||||
|
{
|
||||||
|
return $this->driver->resolve($analyzer)->analyze($this);
|
||||||
|
}
|
||||||
|
|
||||||
public function encode(EncoderInterface $encoder): EncodedImage
|
public function encode(EncoderInterface $encoder): EncodedImage
|
||||||
{
|
{
|
||||||
return $this->driver->resolve($encoder)->encode($this);
|
return $this->driver->resolve($encoder)->encode($this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function width(): int
|
||||||
|
{
|
||||||
|
return $this->analyze(new WidthAnalyzer());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function height(): int
|
||||||
|
{
|
||||||
|
return $this->analyze(new HeightAnalyzer());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function size(): SizeInterface
|
||||||
|
{
|
||||||
|
return new Rectangle($this->width(), $this->height());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function colorspace(): ColorspaceInterface
|
||||||
|
{
|
||||||
|
return $this->analyze(new ColorspaceAnalyzer());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function resolution(): ResolutionInterface
|
||||||
|
{
|
||||||
|
return $this->analyze(new ResolutionAnalyzer());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function pickColor(int $x, int $y, int $frame_key = 0): ColorInterface
|
||||||
|
{
|
||||||
|
return $this->analyze(new PixelColorAnalyzer($x, $y, $frame_key));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function pickColors(int $x, int $y): CollectionInterface
|
||||||
|
{
|
||||||
|
return $this->analyze(new PixelColorsAnalyzer($x, $y));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function profile(): ProfileInterface
|
||||||
|
{
|
||||||
|
return $this->analyze(new ProfileAnalyzer());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function sharpen(int $amount = 10): ImageInterface
|
||||||
|
{
|
||||||
|
return $this->modify(new SharpenModifier($amount));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
8
src/Interfaces/AnalyzerInterface.php
Normal file
8
src/Interfaces/AnalyzerInterface.php
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Intervention\Image\Interfaces;
|
||||||
|
|
||||||
|
interface AnalyzerInterface
|
||||||
|
{
|
||||||
|
public function analyze(ImageInterface $image): mixed;
|
||||||
|
}
|
@@ -5,4 +5,5 @@ namespace Intervention\Image\Interfaces;
|
|||||||
interface ColorProcessorInterface
|
interface ColorProcessorInterface
|
||||||
{
|
{
|
||||||
public function colorToNative(ColorInterface $color);
|
public function colorToNative(ColorInterface $color);
|
||||||
|
public function nativeToColor(mixed $native): ColorInterface;
|
||||||
}
|
}
|
||||||
|
@@ -8,10 +8,7 @@ interface CoreInterface extends Traversable
|
|||||||
{
|
{
|
||||||
public function native();
|
public function native();
|
||||||
public function count(): int;
|
public function count(): int;
|
||||||
public function width(): int;
|
|
||||||
public function height(): int;
|
|
||||||
public function frame(int $position): FrameInterface;
|
public function frame(int $position): FrameInterface;
|
||||||
public function loops(): int;
|
public function loops(): int;
|
||||||
public function setLoops(int $loops): CoreInterface;
|
public function setLoops(int $loops): CoreInterface;
|
||||||
public function colorspace(): ColorspaceInterface;
|
|
||||||
}
|
}
|
||||||
|
@@ -4,8 +4,10 @@ namespace Intervention\Image\Interfaces;
|
|||||||
|
|
||||||
interface DriverInterface
|
interface DriverInterface
|
||||||
{
|
{
|
||||||
|
public function id(): string;
|
||||||
public function resolve(object $input): object;
|
public function resolve(object $input): object;
|
||||||
public function createImage(int $width, int $height): ImageInterface;
|
public function createImage(int $width, int $height): ImageInterface;
|
||||||
public function handleInput(mixed $input): ImageInterface|ColorInterface;
|
public function handleInput(mixed $input): ImageInterface|ColorInterface;
|
||||||
|
public function colorProcessor(ColorspaceInterface $colorspace): ColorProcessorInterface;
|
||||||
public function colorToNative(ColorInterface $color, ColorspaceInterface $colorspace): mixed;
|
public function colorToNative(ColorInterface $color, ColorspaceInterface $colorspace): mixed;
|
||||||
}
|
}
|
||||||
|
@@ -15,6 +15,7 @@ interface ImageInterface extends IteratorAggregate, Countable
|
|||||||
public function size(): SizeInterface;
|
public function size(): SizeInterface;
|
||||||
public function encode(EncoderInterface $encoder): EncodedImage;
|
public function encode(EncoderInterface $encoder): EncodedImage;
|
||||||
public function modify(ModifierInterface $modifier): ImageInterface;
|
public function modify(ModifierInterface $modifier): ImageInterface;
|
||||||
|
public function analyze(AnalyzerInterface $analyzer): mixed;
|
||||||
public function isAnimated(): bool;
|
public function isAnimated(): bool;
|
||||||
public function loops(): int;
|
public function loops(): int;
|
||||||
public function exif(?string $query = null): mixed;
|
public function exif(?string $query = null): mixed;
|
||||||
|
Reference in New Issue
Block a user