Файл: vendor/intervention/image/src/Colors/Oklch/Colorspace.php
Строк: 180
<?php
declare(strict_types=1);
namespace InterventionImageColorsOklch;
use InterventionImageColorsAbstractColorspace;
use InterventionImageColorsCmykColor as CmykColor;
use InterventionImageColorsHslColor as HslColor;
use InterventionImageColorsHsvColor as HsvColor;
use InterventionImageColorsOklchChannelsAlpha;
use InterventionImageColorsOklabColor as OklabColor;
use InterventionImageColorsOklabColorspace as Oklab;
use InterventionImageColorsOklchChannelsChroma;
use InterventionImageColorsOklchChannelsHue;
use InterventionImageColorsOklchChannelsLightness;
use InterventionImageColorsOklchColor as OklchColor;
use InterventionImageColorsRgbColor as RgbColor;
use InterventionImageColorsRgbColorspace as Rgb;
use InterventionImageColorsRgbNamedColor;
use InterventionImageExceptionsColorException;
use InterventionImageExceptionsInvalidArgumentException;
use InterventionImageInterfacesColorInterface;
use TypeError;
class Colorspace extends AbstractColorspace
{
/**
* Channel class names of colorspace.
*
* @var array<string>
*/
public static array $channels = [
Lightness::class,
Chroma::class,
Hue::class,
Alpha::class,
];
/**
* {@inheritdoc}
*
* @see ColorspaceInterface::colorFromNormalized()
*
* @throws InvalidArgumentException
*/
public static function colorFromNormalized(array $normalized): OklchColor
{
if (!in_array(count($normalized), [3, 4])) {
throw new InvalidArgumentException('Number of color channels must be 3 or 4 for ' . static::class);
}
// add alpha value if missing
$normalized = count($normalized) === 3 ? array_pad($normalized, 4, 1) : $normalized;
return new Color(...array_map(
function (string $channel, null|float $normalized) {
try {
return $channel::fromNormalized($normalized);
} catch (TypeError $e) {
throw new InvalidArgumentException(
'Normalized color value must be in range 0 to 1',
previous: $e,
);
}
},
self::$channels,
$normalized,
));
}
/**
* {@inheritdoc}
*
* @see ColorspaceInterface::importColor()
*
* @throws ColorException
*/
public function importColor(ColorInterface $color): OklchColor
{
return match ($color::class) {
CmykColor::class,
HsvColor::class,
NamedColor::class,
HslColor::class => $this->importViaRgbColor($color),
OklabColor::class => $this->importOklabColor($color),
RgbColor::class => $this->importRgbColor($color),
OklchColor::class => $color,
default => throw new ColorException(
'Unable to import color ' . $color::class . ' to ' . $this::class,
),
};
}
/**
* Import given OKLAB color OKLCH colorspace.
*
* @throws ColorException
*/
private function importOklabColor(OklabColor $color): OklchColor
{
$a = $color->a()->value();
$b = $color->b()->value();
$c = sqrt($a * $a + $b * $b);
$h = rad2deg(atan2($b, $a));
$h = $h < 0 ? $h + 360 : $h;
try {
return new Color($color->lightness()->value(), $c, $h, $color->alpha()->normalized());
} catch (InvalidArgumentException $e) {
throw new ColorException(
'Failed to import color ' . $color::class . ' to ' . $this::class,
previous: $e,
);
}
}
/**
* Import given RGB color to OKLCH color space.
*
* @throws ColorException
*/
private function importRgbColor(RgbColor $color): OklchColor
{
try {
$color = $color->toColorspace(Oklab::class);
} catch (InvalidArgumentException $e) {
throw new ColorException(
'Failed to import color ' . $color::class . ' to ' . $this::class,
previous: $e,
);
}
if (!$color instanceof OklabColor) {
throw new ColorException('Failed to import color ' . $color::class . ' to ' . $this::class);
}
return $this->importOklabColor($color);
}
/**
* Import given color to OKLCH color space by converting it to RGB first.
*
* @throws ColorException
*/
private function importViaRgbColor(NamedColor|HslColor|HsvColor|CmykColor $color): OklchColor
{
try {
$color = $color->toColorspace(Rgb::class)->toColorspace($this::class);
} catch (InvalidArgumentException $e) {
throw new ColorException(
'Failed to import color ' . $color::class . ' to ' . $this::class,
previous: $e,
);
}
if (!$color instanceof OklchColor) {
throw new ColorException('Failed to import color ' . $color::class . ' to ' . $this::class);
}
return $color;
}
}