Вход Регистрация
Файл: vendor/intervention/image/src/Colors/Hsl/Colorspace.php
Строк: 191
<?php

declare(strict_types=1);

namespace 
InterventionImageColorsHsl;

use 
InterventionImageColorsCmykColor as CmykColor;
use 
InterventionImageColorsRgbColor as RgbColor;
use 
InterventionImageColorsHsvColor as HsvColor;
use 
InterventionImageColorsRgbColorspace as RgbColorspace;
use 
InterventionImageExceptionsColorException;
use 
InterventionImageInterfacesColorChannelInterface;
use 
InterventionImageInterfacesColorInterface;
use 
InterventionImageInterfacesColorspaceInterface;

class 
Colorspace implements ColorspaceInterface
{
    
/**
     * Channel class names of colorspace
     *
     * @var array<string>
     */
    
public static array $channels = [
        
ChannelsHue::class,
        
ChannelsSaturation::class,
        
ChannelsLuminance::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
        
));
    }

    
/**
     * @param ColorInterface $color
     * @return ColorInterface
     * @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,
        };
    }

    
/**
     * @param ColorInterface $color
     * @return ColorInterface
     * @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)),
        );
    }

    
/**
     * @param ColorInterface $color
     * @return ColorInterface
     * @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)),
        );
    }
}
Онлайн: 3
Реклама