Passed
Push — master ( 5153e5...af085a )
by Sebastian
05:42 queued 30s
created

RGBAColor_Converter   A

Complexity

Total Complexity 22

Size/Duplication

Total Lines 256
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
wmc 22
eloc 79
c 2
b 0
f 0
dl 0
loc 256
rs 10

12 Methods

Rating   Name   Duplication   Size   Complexity  
A parseHEX8() 0 7 1
A int2hex() 0 9 2
A hex2color() 0 28 4
A percent2int() 0 4 1
A array2hex() 0 15 3
A color2readable() 0 18 2
A parseHEX3() 0 7 1
A parseHEX6() 0 7 1
A color2HEX() 0 3 1
A requireValidColorArray() 0 16 2
A int2percent() 0 3 1
A isColorArray() 0 17 3
1
<?php
2
/**
3
 * File containing the class {@see RGBAColor_Converter}.
4
 *
5
 * @package AppUtils
6
 * @subpackage RGBAColor
7
 * @see RGBAColor_Converter
8
 */
9
10
declare(strict_types=1);
11
12
namespace AppUtils;
13
14
/**
15
 * The converter static class is used to convert between color
16
 * information formats.
17
 *
18
 * @package AppUtils
19
 * @subpackage RGBAColor
20
 * @author Sebastian Mordziol <[email protected]>
21
 */
22
class RGBAColor_Converter
23
{
24
    /**
25
     * Converts the color to a HEX color value. This is either
26
     * a RRGGBB or RRGGBBAA string, depending on whether there
27
     * is an alpha channel value.
28
     *
29
     * NOTE: The HEX letters are always uppercase.
30
     *
31
     * @param RGBAColor $color
32
     * @return string
33
     * @throws RGBAColor_Exception
34
     */
35
    public static function color2HEX(RGBAColor $color) : string
36
    {
37
        return self::array2hex($color->toArray());
38
    }
39
40
    /**
41
     * Checks if the array is a valid color array with
42
     * all expected color keys present. The `alpha` key
43
     * is optional. If it's not valid, throws an exception.
44
     *
45
     * @param array $color
46
     * @throws RGBAColor_Exception
47
     * @see RGBAColor::ERROR_INVALID_COLOR_ARRAY
48
     */
49
    public static function requireValidColorArray(array $color) : void
50
    {
51
        if(self::isColorArray($color))
52
        {
53
            return;
54
        }
55
56
        throw new RGBAColor_Exception(
57
            'Not a valid color array.',
58
            sprintf(
59
                'The color array is in the wrong format, or is missing required keys. '.
60
                'Given: '.PHP_EOL.
61
                '%s',
62
                parseVariable($color)->toString()
63
            ),
64
            RGBAColor::ERROR_INVALID_COLOR_ARRAY
65
        );
66
    }
67
68
    /**
69
     * Checks whether the specified array contains all required
70
     * color keys.
71
     *
72
     * @param array $color
73
     * @return bool
74
     */
75
    public static function isColorArray(array $color) : bool
76
    {
77
        $keys = array(
78
            RGBAColor::COMPONENT_RED,
79
            RGBAColor::COMPONENT_GREEN,
80
            RGBAColor::COMPONENT_BLUE
81
        );
82
83
        foreach($keys as $key)
84
        {
85
            if(!isset($color[$key]))
86
            {
87
                return false;
88
            }
89
        }
90
91
        return true;
92
    }
93
94
    /**
95
     * @param array{red:int,green:int,blue:int,alpha:int} $color
96
     * @return string
97
     */
98
    public static function array2hex(array $color) : string
99
    {
100
        self::requireValidColorArray($color);
101
102
        $hex =
103
            self::int2hex($color[RGBAColor::COMPONENT_RED]).
104
            self::int2hex($color[RGBAColor::COMPONENT_GREEN]).
105
            self::int2hex($color[RGBAColor::COMPONENT_BLUE]);
106
107
        if(isset($color[RGBAColor::COMPONENT_ALPHA]) && $color[RGBAColor::COMPONENT_ALPHA] < 255)
108
        {
109
            $hex .= self::int2hex($color[RGBAColor::COMPONENT_ALPHA]);
110
        }
111
112
        return strtoupper($hex);
113
    }
114
115
    /**
116
     * Converts an integer to a HEX color string. This differs
117
     * from the native `dechex()` function, in that it will
118
     * return `00` for the color string instead of the default
119
     * `0` provided by `dechex()`.
120
     *
121
     * @param int $int
122
     * @return string
123
     */
124
    private static function int2hex(int $int) : string
125
    {
126
        $str = dechex($int);
127
        if(strlen($str) === 1)
128
        {
129
            $str = $str.$str;
130
        }
131
132
        return $str;
133
    }
134
135
    /**
136
     * Human-readable label of the color. Automatically
137
     * switches between RGBA and RGB depending on whether
138
     * the color has any transparency.
139
     *
140
     * @param RGBAColor $color
141
     * @return string
142
     * @throws RGBAColor_Exception
143
     */
144
    public static function color2readable(RGBAColor $color) : string
145
    {
146
        if($color->hasTransparency())
147
        {
148
            return sprintf(
149
                'RGBA(%s %s %s %s)',
150
                $color->getRed(),
151
                $color->getGreen(),
152
                $color->getBlue(),
153
                $color->getAlpha()
154
            );
155
        }
156
157
        return sprintf(
158
            'RGB(%s %s %s)',
159
            $color->getRed(),
160
            $color->getGreen(),
161
            $color->getBlue()
162
        );
163
    }
164
165
    /**
166
     * Converts a color value to a percentage.
167
     * @param int $colorValue 0-255
168
     * @return float
169
     */
170
    public static function int2percent(int $colorValue) : float
171
    {
172
        return $colorValue * 100 / 255;
173
    }
174
175
    /**
176
     * Converts a percentage to an integer color value.
177
     * @param float $percent
178
     * @return int 0-255
179
     */
180
    public static function percent2int(float $percent) : int
181
    {
182
        $value = $percent * 255 / 100;
183
        return intval(round($value, 0, PHP_ROUND_HALF_UP));
184
    }
185
186
    /**
187
     * Parses a HEX color value, and converts it to
188
     * an RGBA color array.
189
     *
190
     * Examples:
191
     *
192
     * <pre>
193
     * $color = RGBAColor_Utilities::parseHexColor('CCC');
194
     * $color = RGBAColor_Utilities::parseHexColor('CCDDEE');
195
     * $color = RGBAColor_Utilities::parseHexColor('CCDDEEFA');
196
     * </pre>
197
     *
198
     * @param string $hex
199
     * @return array{red:int,green:int,blue:int,alpha:int}
200
     *
201
     * @throws RGBAColor_Exception
202
     * @see RGBAColor::ERROR_INVALID_HEX_LENGTH
203
     */
204
    public static function hex2color(string $hex) : array
205
    {
206
        $hex = ltrim($hex, '#'); // Remove the hash if present
207
        $hex = strtoupper($hex);
208
        $length = strlen($hex);
209
210
        if($length === 3)
211
        {
212
            return self::parseHEX3($hex);
213
        }
214
        else if($length === 6)
215
        {
216
            return self::parseHEX6($hex);
217
        }
218
        else if ($length === 8)
219
        {
220
            return self::parseHEX8($hex);
221
        }
222
223
        throw new RGBAColor_Exception(
224
            'Invalid HEX color value.',
225
            sprintf(
226
                'The hex string [%s] has an invalid length ([%s] characters). '.
227
                'It must be either 6 characters (RRGGBB) or 8 characters (RRGGBBAA) long.',
228
                $hex,
229
                $length
230
            ),
231
            RGBAColor::ERROR_INVALID_HEX_LENGTH
232
        );
233
    }
234
235
    /**
236
     * Parses a three-letter HEX color string to a color array.
237
     *
238
     * @param string $hex
239
     * @return array{red:int,green:int,blue:int,alpha:int}
240
     */
241
    private static function parseHEX3(string $hex) : array
242
    {
243
        return array(
244
            RGBAColor::COMPONENT_RED => hexdec(str_repeat(substr($hex, 0, 1), 2)),
245
            RGBAColor::COMPONENT_GREEN => hexdec(str_repeat(substr($hex, 1, 1), 2)),
246
            RGBAColor::COMPONENT_BLUE => hexdec(str_repeat(substr($hex, 2, 1), 2)),
247
            RGBAColor::COMPONENT_ALPHA => 255
248
        );
249
    }
250
251
    /**
252
     * Parses a six-letter HEX color string to a color array.
253
     * @param string $hex
254
     * @return array{red:int,green:int,blue:int,alpha:int}
255
     */
256
    private static function parseHEX6(string $hex) : array
257
    {
258
        return array(
259
            RGBAColor::COMPONENT_RED => hexdec(substr($hex, 0, 2)),
260
            RGBAColor::COMPONENT_GREEN => hexdec(substr($hex, 2, 2)),
261
            RGBAColor::COMPONENT_BLUE => hexdec(substr($hex, 4, 2)),
262
            RGBAColor::COMPONENT_ALPHA => 255
263
        );
264
    }
265
266
    /**
267
     * Parses an eight-letter HEX color string (with alpha) to a color array.
268
     * @param string $hex
269
     * @return array{red:int,green:int,blue:int,alpha:int}
270
     */
271
    private static function parseHEX8(string $hex) : array
272
    {
273
        return array(
274
            RGBAColor::COMPONENT_RED => hexdec(substr($hex, 0, 2)),
275
            RGBAColor::COMPONENT_GREEN => hexdec(substr($hex, 2, 2)),
276
            RGBAColor::COMPONENT_BLUE => hexdec(substr($hex, 4, 2)),
277
            RGBAColor::COMPONENT_ALPHA => hexdec(substr($hex, 6, 2))
278
        );
279
    }
280
}
281