Completed
Push — master ( d7b920...15274c )
by ARCANEDEV
7s
created

HSVTrait   A

Complexity

Total Complexity 19

Size/Duplication

Total Lines 161
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 0

Test Coverage

Coverage 96.15%

Importance

Changes 0
Metric Value
wmc 19
lcom 1
cbo 0
dl 0
loc 161
ccs 50
cts 52
cp 0.9615
rs 10
c 0
b 0
f 0

7 Methods

Rating   Name   Duplication   Size   Complexity  
A rgbToHsv() 0 4 1
B fromRgbToHsv() 0 32 4
A hsvToRgb() 0 4 1
A fromHsvToRgb() 0 11 1
B calculateRgbWithHueAndChroma() 0 15 7
A calculateXPrime() 0 6 2
A sanitizeHsvValue() 0 7 3
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 Functions
13
     | ------------------------------------------------------------------------------------------------
14
     */
15
    /**
16
     * Convert an RGB color to an HSV array (alias).
17
     *
18
     * @see    fromRgbToHsv
19
     *
20
     * @param  int  $red
21
     * @param  int  $green
22
     * @param  int  $blue
23
     *
24
     * @return array
25
     */
26 8
    public static function rgbToHsv($red, $green, $blue)
27
    {
28 8
        return (new self())->fromRgbToHsv($red, $green, $blue);
29
    }
30
31
    /**
32
     * Convert an RGB color to an HSV array.
33
     *
34
     * @param  int  $red
35
     * @param  int  $green
36
     * @param  int  $blue
37
     *
38
     * @return array
39
     */
40 16
    public function fromRgbToHsv($red, $green, $blue)
41
    {
42 16
        $red        = $red   / 255;
43 16
        $green      = $green / 255;
44 16
        $blue       = $blue  / 255;
45 16
        $maxRGB     = max($red, $green, $blue);
46 16
        $minRGB     = min($red, $green, $blue);
47
48 16
        $hue        = 0;
49 16
        $saturation = 0;
50 16
        $value      = 100 * $maxRGB;
51 16
        $chroma     = $maxRGB - $minRGB;
52
53 16
        if ($chroma != 0) {
54 16
            $saturation = 100 * ($chroma / $maxRGB);
55
56 16
            if ($red == $minRGB)
57 14
                $hue = 3 - (($green - $blue) / $chroma);
58 16
            elseif ($blue == $minRGB)
59 16
                $hue = 1 - (($red - $green) / $chroma);
60
            else // $green == $minRGB
61 8
                $hue = 5 - (($blue - $red) / $chroma);
62
63 16
            $hue = 60 * $hue;
64 12
        }
65
66
        return [
67 16
            round($hue, 2),
68 16
            round($saturation, 2),
69 16
            round($value, 2),
70 12
        ];
71
    }
72
73
    /**
74
     * Convert an HSV color to an RGB array (alias).
75
     *
76
     * @see    fromHsvToRgb
77
     *
78
     * @param  float|int  $hue
79
     * @param  float|int  $saturation
80
     * @param  float|int  $value
81
     *
82
     * @return array
83
     */
84 8
    public static function hsvToRgb($hue, $saturation, $value)
85
    {
86 8
        return (new self)->fromHsvToRgb($hue, $saturation, $value);
87
    }
88
89
    /**
90
     * Convert an HSV color to an RGB array.
91
     *
92
     * @param  float|int  $hue
93
     * @param  float|int  $saturation
94
     * @param  float|int  $value
95
     *
96
     * @return array
97
     */
98 16
    public function fromHsvToRgb($hue, $saturation, $value)
99
    {
100
        // Lightness: 0.0 - 1.0
101 16
        $lightness = $this->sanitizeHsvValue($value, 0, 100) / 100.0;
102
        // Chroma:    0.0 - 1.0
103 16
        $chroma    = $lightness * ($this->sanitizeHsvValue($saturation, 0, 100) / 100.0);
104
105 16
        return array_map(function ($color) use ($lightness, $chroma) {
106 16
            return (int) round(($color + ($lightness - $chroma)) * 255);
107 16
        }, $this->calculateRgbWithHueAndChroma($hue, $chroma));
108
    }
109
110
    /* ------------------------------------------------------------------------------------------------
111
     |  Other Functions
112
     | ------------------------------------------------------------------------------------------------
113
     */
114
    /**
115
     * Calculate RGB with hue and chroma.
116
     *
117
     * @param  float|int  $hue
118
     * @param  float|int  $chroma
119
     *
120
     * @return array
121
     */
122 16
    protected function calculateRgbWithHueAndChroma($hue, $chroma)
123
    {
124 16
        $hPrime = $this->sanitizeHsvValue($hue, 0, 360) / 60.0;
125 16
        $xPrime = $this->calculateXPrime($hPrime, $chroma);
126
127 16
        switch (floor($hPrime)) {
128 16
            case 0:  return [$chroma, $xPrime, 0.0];
129 16
            case 1:  return [$xPrime, $chroma, 0.0];
130 8
            case 2:  return [0.0, $chroma, $xPrime];
131 8
            case 3:  return [0.0, $xPrime, $chroma];
132 8
            case 4:  return [$xPrime, 0.0, $chroma];
133 8
            case 5:  return [$chroma, 0.0, $xPrime];
134
            default: return [0.0, 0.0, 0.0];
135
        }
136
    }
137
138
    /**
139
     * Calculate X-Prime.
140
     *
141
     * @param  float|int  $hPrime
142
     * @param  float|int  $chroma
143
     *
144
     * @return float|int
145
     */
146 16
    protected function calculateXPrime($hPrime, $chroma)
147
    {
148 16
        while ($hPrime >= 2.0) $hPrime -= 2.0;
149
150 16
        return $chroma * (1 - abs($hPrime - 1));
151
    }
152
153
    /**
154
     * Sanitize HSV value.
155
     *
156
     * @param  int  $value
157
     * @param  int  $min
158
     * @param  int  $max
159
     *
160
     * @return float|int
161
     */
162 16
    protected function sanitizeHsvValue($value, $min, $max)
163
    {
164 16
        if ($value < $min) return $min;
165 16
        if ($value > $max) return $max;
166
167 16
        return $value;
168
    }
169
}
170