Completed
Pull Request — master (#1)
by ARCANEDEV
09:00
created

HSVTrait::calculateRgbWithHueAndChroma()   B

Complexity

Conditions 7
Paths 7

Size

Total Lines 15
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 7.2269

Importance

Changes 2
Bugs 0 Features 0
Metric Value
dl 0
loc 15
ccs 10
cts 12
cp 0.8333
rs 8.2222
c 2
b 0
f 0
cc 7
eloc 11
nc 7
nop 2
crap 7.2269
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 16
    public static function rgbToHsv($red, $green, $blue)
25
    {
26 16
        $red        = $red   / 255;
27 16
        $green      = $green / 255;
28 16
        $blue       = $blue  / 255;
29 16
        $maxRGB     = max($red, $green, $blue);
30 16
        $minRGB     = min($red, $green, $blue);
31
32 16
        $hue        = 0;
33 16
        $saturation = 0;
34 16
        $value      = 100 * $maxRGB;
35 16
        $chroma     = $maxRGB - $minRGB;
36
37 16
        if ($chroma != 0) {
38 16
            $saturation = 100 * ($chroma / $maxRGB);
39
40 16
            if ($red == $minRGB)
41 12
                $hue = 3 - (($green - $blue) / $chroma);
42 16
            elseif ($blue == $minRGB)
43 16
                $hue = 1 - (($red - $green) / $chroma);
44
            else // $green == $minRGB
45 8
                $hue = 5 - (($blue - $red) / $chroma);
46
47 16
            $hue = 60 * $hue;
48 8
        }
49
50
        return [
51 16
            round($hue, 2),
52 16
            round($saturation, 2),
53 16
            round($value, 2),
54 8
        ];
55
    }
56
57
    /**
58
     * Convert an HSV color to an RGB array.
59
     *
60
     * @param  float|int  $hue
61
     * @param  float|int  $saturation
62
     * @param  float|int  $value
63
     *
64
     * @return array
65
     */
66 16
    public static function hsvToRgb($hue, $saturation, $value)
67
    {
68 16
        $lightness = self::sanitizeHsvValue($value, 0, 100) / 100.0;                     // Lightness:  0.0-1.0
69 16
        $chroma    = $lightness * (self::sanitizeHsvValue($saturation, 0, 100) / 100.0); // Chroma:     0.0-1.0
70
71 16
        return array_map(function ($color) use ($lightness, $chroma) {
72 16
            return (int) round(($color + ($lightness - $chroma)) * 255);
73 16
        }, self::calculateRgbWithHueAndChroma($hue, $chroma));
74
    }
75
76
    /* ------------------------------------------------------------------------------------------------
77
     |  Other Functions
78
     | ------------------------------------------------------------------------------------------------
79
     */
80
    /**
81
     * Calculate RGB with hue and chroma.
82
     *
83
     * @param  float|int  $hue
84
     * @param  float|int  $chroma
85
     *
86
     * @return array
87
     */
88 16
    protected static function calculateRgbWithHueAndChroma($hue, $chroma)
89
    {
90 16
        $hPrime = self::sanitizeHsvValue($hue, 0, 360) / 60.0;
91 16
        $xPrime = self::calculateXPrime($hPrime, $chroma);
92
93 16
        switch (floor($hPrime)) {
94 16
            case 0:  return [$chroma, $xPrime, 0.0];
95 16
            case 1:  return [$xPrime, $chroma, 0.0];
96 8
            case 2:  return [0.0, $chroma, $xPrime];
97 8
            case 3:  return [0.0, $xPrime, $chroma];
98 8
            case 4:  return [$xPrime, 0.0, $chroma];
99 8
            case 5:  return [$chroma, 0.0, $xPrime];
100
            default: return [0.0, 0.0, 0.0];
101
        }
102
    }
103
104
    /**
105
     * Calculate X-Prime.
106
     *
107
     * @param  float|int  $hPrime
108
     * @param  float|int  $chroma
109
     *
110
     * @return float|int
111
     */
112 16
    protected static function calculateXPrime($hPrime, $chroma)
113
    {
114 16
        while ($hPrime >= 2.0) $hPrime -= 2.0;
115
116 16
        return $chroma * (1 - abs($hPrime - 1));
117
    }
118
119
    /**
120
     * Sanitize HSV value.
121
     *
122
     * @param  int  $value
123
     * @param  int  $min
124
     * @param  int  $max
125
     *
126
     * @return float|int
127
     */
128 16
    protected static function sanitizeHsvValue($value, $min, $max)
129
    {
130 16
        if ($value < $min) return $min;
131 16
        if ($value > $max) return $max;
132
133 16
        return $value;
134
    }
135
}
136