Completed
Pull Request — master (#1)
by ARCANEDEV
05:02
created

HSVTrait   A

Complexity

Total Complexity 17

Size/Duplication

Total Lines 129
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 0

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 17
lcom 1
cbo 0
dl 0
loc 129
rs 10
c 1
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
B rgbToHsv() 0 33 4
A hsvToRgb() 0 9 1
B calculateRgbWithHueAndChroma() 0 16 7
A calculateXPrime() 0 6 2
A sanitizeHsvValue() 0 7 3
1
<?php namespace Arcanedev\Color\Helpers\Converters;
2
3
/**
4
 * Class     HSVTrait
5
 *
6
 * @package  Arcanedev\Color\Helpers\Converters
7
 * @author   ARCANEDEV <[email protected]>
8
 */
9
trait HSVTrait
10
{
11
    /* ------------------------------------------------------------------------------------------------
12
     |  Main Functions
13
     | ------------------------------------------------------------------------------------------------
14
     */
15
    /**
16
     * Convert an RGB color to an HSV array.
17
     *
18
     * @param  int  $red
19
     * @param  int  $green
20
     * @param  int  $blue
21
     *
22
     * @return array
23
     */
24
    public static function rgbToHsv($red, $green, $blue)
25
    {
26
        $red   = ($red / 255);
27
        $green = ($green / 255);
28
        $blue  = ($blue / 255);
29
30
        $maxRGB     = max($red, $green, $blue);
31
        $minRGB     = min($red, $green, $blue);
32
        $chroma     = $maxRGB - $minRGB;
33
34
        $hue        = 0;
35
        $saturation = 0;
36
        $value      = 100 * $maxRGB;
37
38
        if ($chroma != 0) {
39
            $saturation = 100 * ($chroma / $maxRGB);
40
41
            if ($red == $minRGB)
42
                $hue = 3 - (($green - $blue) / $chroma);
43
            elseif ($blue == $minRGB)
44
                $hue = 1 - (($red - $green) / $chroma);
45
            else // $green == $minRGB
46
                $hue = 5 - (($blue - $red) / $chroma);
47
48
            $hue = 60 * $hue;
49
        }
50
51
        return [
52
            round($hue, 2),
53
            round($saturation, 2),
54
            round($value, 2),
55
        ];
56
    }
57
58
    /**
59
     * Convert an HSV color to an RGB array.
60
     *
61
     * @param  float|int  $hue
62
     * @param  float|int  $saturation
63
     * @param  float|int  $value
64
     *
65
     * @return array
66
     */
67
    public static function hsvToRgb($hue, $saturation, $value)
68
    {
69
        $lightness = self::sanitizeHsvValue($value, 0, 100) / 100.0;                     // Lightness:  0.0-1.0
70
        $chroma    = $lightness * (self::sanitizeHsvValue($saturation, 0, 100) / 100.0); // Chroma:     0.0-1.0
71
72
        return array_map(function ($color) use ($lightness, $chroma) {
73
            return (int) round(($color + ($lightness - $chroma)) * 255);
74
        }, self::calculateRgbWithHueAndChroma($hue, $chroma));
75
    }
76
77
    /* ------------------------------------------------------------------------------------------------
78
     |  Other Functions
79
     | ------------------------------------------------------------------------------------------------
80
     */
81
    /**
82
     * Calculate RGB with hue and chroma.
83
     *
84
     * @param  float|int  $hue
85
     * @param  float|int  $chroma
86
     *
87
     * @return array
88
     */
89
    protected static function calculateRgbWithHueAndChroma($hue, $chroma)
90
    {
91
        $hPrime = self::sanitizeHsvValue($hue, 0, 360) / 60.0;
92
        $xPrime = self::calculateXPrime($hPrime, $chroma);
93
94
        switch (floor($hPrime)) {
95
            case 0: return [$chroma, $xPrime, 0.0];
96
            case 1: return [$xPrime, $chroma, 0.0];
97
            case 2: return [0.0, $chroma, $xPrime];
98
            case 3: return [0.0, $xPrime, $chroma];
99
            case 4: return [$xPrime, 0.0, $chroma];
100
            case 5: return [$chroma, 0.0, $xPrime];
101
        }
102
103
        return [0.0, 0.0, 0.0];
104
    }
105
106
    /**
107
     * Calculate X-Prime.
108
     *
109
     * @param  float|int  $hPrime
110
     * @param  float|int  $chroma
111
     *
112
     * @return float|int
113
     */
114
    protected static function calculateXPrime($hPrime, $chroma)
115
    {
116
        while ($hPrime >= 2.0) $hPrime -= 2.0;
117
118
        return $chroma * (1 - abs($hPrime - 1));
119
    }
120
121
    /**
122
     * Sanitize HSV value.
123
     *
124
     * @param  int  $value
125
     * @param  int  $min
126
     * @param  int  $max
127
     *
128
     * @return float|int
129
     */
130
    protected static function sanitizeHsvValue($value, $min, $max)
131
    {
132
        if ($value < $min) return $min;
133
        if ($value > $max) return $max;
134
135
        return $value;
136
    }
137
}
138