HSVTrait   A
last analyzed

Complexity

Total Complexity 17

Size/Duplication

Total Lines 196
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 0

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 17
lcom 1
cbo 0
dl 0
loc 196
ccs 56
cts 56
cp 1
rs 10
c 0
b 0
f 0

9 Methods

Rating   Name   Duplication   Size   Complexity  
A rgbToHsv() 0 4 1
A hsvToRgb() 0 4 1
A fromHsvToRgb() 0 11 1
A calculateRgbWithHueAndChroma() 0 11 2
A calculateXPrime() 0 7 2
A fromRgbToHsv() 0 22 2
A recalculateHue() 0 14 4
A sanitizeHsvValue() 0 7 3
A getColorsRange() 0 11 1
1
<?php namespace Arcanedev\Color\Converters;
2
3
/**
4
 * Trait     HSVTrait
5
 *
6
 * @package  Arcanedev\Color\Converters
7
 * @author   ARCANEDEV <[email protected]>
8
 */
9
trait HSVTrait
10
{
11
    /* -----------------------------------------------------------------
12
     |  Main Methods
13
     | -----------------------------------------------------------------
14
     */
15
16
    /**
17
     * Convert an RGB color to an HSV array (alias).
18
     *
19
     * @see    fromRgbToHsv
20
     *
21
     * @param  int  $red
22
     * @param  int  $green
23
     * @param  int  $blue
24
     *
25
     * @return array
26
     */
27 3
    public static function rgbToHsv($red, $green, $blue)
28
    {
29 3
        return (new static)->fromRgbToHsv($red, $green, $blue);
30
    }
31
32
    /**
33
     * Convert an RGB color to an HSV array.
34
     *
35
     * @param  int  $red
36
     * @param  int  $green
37
     * @param  int  $blue
38
     *
39
     * @return array
40
     */
41 6
    public function fromRgbToHsv($red, $green, $blue)
42
    {
43 6
        $red        = $red   / 255;
44 6
        $green      = $green / 255;
45 6
        $blue       = $blue  / 255;
46 6
        $maxRGB     = max($red, $green, $blue);
47 6
        $minRGB     = min($red, $green, $blue);
48
49 6
        $hue        = 0;
50 6
        $saturation = 0;
51 6
        $value      = 100 * $maxRGB;
52 6
        $chroma     = $maxRGB - $minRGB;
53
54 6
        if ($chroma != 0) {
55 6
            $saturation = 100 * ($chroma / $maxRGB);
56 6
            $hue        = $this->recalculateHue($red, $green, $blue, $minRGB, $chroma) * 60;
57
        }
58
59 6
        return array_map(function ($value) {
60 6
            return round($value, 2);
61 6
        }, [$hue, $saturation, $value]);
62
    }
63
64
    /**
65
     * Convert an HSV color to an RGB array (alias).
66
     *
67
     * @see    fromHsvToRgb
68
     *
69
     * @param  float|int  $hue
70
     * @param  float|int  $saturation
71
     * @param  float|int  $value
72
     *
73
     * @return array
74
     */
75 3
    public static function hsvToRgb($hue, $saturation, $value)
76
    {
77 3
        return (new static)->fromHsvToRgb($hue, $saturation, $value);
78
    }
79
80
    /**
81
     * Convert an HSV color to an RGB array.
82
     *
83
     * @param  float|int  $hue
84
     * @param  float|int  $saturation
85
     * @param  float|int  $value
86
     *
87
     * @return array
88
     */
89 6
    public function fromHsvToRgb($hue, $saturation, $value)
90
    {
91
        // Lightness: 0.0 - 1.0
92 6
        $lightness = $this->sanitizeHsvValue($value, 0, 100) / 100.0;
93
        // Chroma:    0.0 - 1.0
94 6
        $chroma    = $lightness * ($this->sanitizeHsvValue($saturation, 0, 100) / 100.0);
95
96 6
        return array_map(function ($color) use ($lightness, $chroma) {
97 6
            return (int) round(($color + ($lightness - $chroma)) * 255);
98 6
        }, $this->calculateRgbWithHueAndChroma($hue, $chroma));
99
    }
100
101
    /* -----------------------------------------------------------------
102
     |  Other Methods
103
     | -----------------------------------------------------------------
104
     */
105
106
    /**
107
     * Recalculate the Hue.
108
     *
109
     * @param  float|int  $red
110
     * @param  float|int  $green
111
     * @param  float|int  $blue
112
     * @param  float|int  $minRGB
113
     * @param  float|int  $chroma
114
     *
115
     * @return float|int
116
     */
117 6
    protected function recalculateHue($red, $green, $blue, $minRGB, $chroma)
118
    {
119
        switch ($minRGB) {
120 6
            case $red:
121 3
                return 3 - (($green - $blue) / $chroma);
122
123 6
            case $blue:
124 6
                return 1 - (($red - $green) / $chroma);
125
126 3
            case $green:
127
            default:
128 3
                return 5 - (($blue - $red) / $chroma);
129
        }
130
    }
131
132
    /**
133
     * Calculate RGB with hue and chroma.
134
     *
135
     * @param  float|int  $hue
136
     * @param  float|int  $chroma
137
     *
138
     * @return array
139
     */
140 6
    protected function calculateRgbWithHueAndChroma($hue, $chroma)
141
    {
142 6
        $hPrime = $this->sanitizeHsvValue($hue, 0, 360) / 60.0;
143 6
        $xPrime = $this->calculateXPrime($hPrime, $chroma);
144 6
        $colors = $this->getColorsRange($chroma, $xPrime);
145 6
        $index  = (int) floor($hPrime);
146
147 6
        return array_key_exists($index, $colors)
148 6
            ? $colors[$index]
149 6
            : [0.0, 0.0, 0.0];
150
    }
151
152
    /**
153
     * Calculate X-Prime.
154
     *
155
     * @param  float|int  $hPrime
156
     * @param  float|int  $chroma
157
     *
158
     * @return float|int
159
     */
160 6
    protected function calculateXPrime($hPrime, $chroma)
161
    {
162 6
        while ($hPrime >= 2.0)
163 3
            $hPrime -= 2.0;
164
165 6
        return $chroma * (1 - abs($hPrime - 1));
166
    }
167
168
    /**
169
     * Sanitize HSV value.
170
     *
171
     * @param  int  $value
172
     * @param  int  $min
173
     * @param  int  $max
174
     *
175
     * @return float|int
176
     */
177 6
    protected function sanitizeHsvValue($value, $min, $max)
178
    {
179 6
        if ($value < $min) return $min;
180 6
        if ($value > $max) return $max;
181
182 6
        return $value;
183
    }
184
185
    /**
186
     * Get the colors range.
187
     *
188
     * @param  float|int  $chroma
189
     * @param  float|int  $xPrime
190
     *
191
     * @return array
192
     */
193 6
    protected function getColorsRange($chroma, $xPrime)
194
    {
195
        return [
196 6
            0 => [$chroma, $xPrime, 0.0],
197 6
            1 => [$xPrime, $chroma, 0.0],
198 6
            2 => [0.0, $chroma, $xPrime],
199 6
            3 => [0.0, $xPrime, $chroma],
200 6
            4 => [$xPrime, 0.0, $chroma],
201 6
            5 => [$chroma, 0.0, $xPrime],
202
        ];
203
    }
204
}
205