redgreenblue 0.8.0 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/redgreenblue.rb +20 -18
- data/lib/redgreenblue/24bit.rb +11 -0
- data/lib/redgreenblue/base.rb +2 -2
- data/lib/redgreenblue/cie_1931.rb +51 -0
- data/lib/redgreenblue/cie_1976.rb +105 -0
- data/lib/redgreenblue/gamma.rb +44 -0
- data/lib/redgreenblue/gpl.rb +91 -0
- data/lib/redgreenblue/hsb.rb +61 -0
- data/lib/redgreenblue/hsl.rb +96 -0
- data/lib/redgreenblue/hsv.rb +96 -0
- data/lib/redgreenblue/hsx_shared.rb +94 -0
- data/lib/redgreenblue/inspect.rb +25 -3
- data/lib/redgreenblue/int.rb +22 -0
- data/lib/redgreenblue/lazy.rb +62 -27
- data/lib/redgreenblue/mac.rb +8 -0
- data/lib/redgreenblue/match.rb +21 -0
- data/lib/redgreenblue/math.rb +9 -0
- data/lib/redgreenblue/misc.rb +27 -2
- data/lib/redgreenblue/mix.rb +27 -6
- data/lib/redgreenblue/name.rb +13 -0
- data/lib/redgreenblue/opt/philipshue.rb +17 -2
- data/lib/redgreenblue/os/mac.rb +9 -6
- data/lib/redgreenblue/ostwald.rb +45 -0
- data/lib/redgreenblue/palettes/css.gpl +164 -0
- data/lib/redgreenblue/rgb565.rb +0 -5
- data/lib/redgreenblue/version.rb +9 -1
- data/lib/redgreenblue/view.rb +34 -0
- data/lib/redgreenblue/web.rb +55 -0
- metadata +23 -6
- data/lib/redgreenblue/cie.rb +0 -62
- data/lib/redgreenblue/hsl_hsv.rb +0 -59
@@ -0,0 +1,21 @@
|
|
1
|
+
class RGB
|
2
|
+
|
3
|
+
# Matches this color to a set of colors by calculating their euclidean distance.
|
4
|
+
#
|
5
|
+
# Returns the given set of colors with their distance from this color, sorted by distance (nearest color first).
|
6
|
+
# @example What is nearer: red, grey or white?
|
7
|
+
# RGB.hex('f9c').match_distance [RGB.red, RGB.grey, RGB.white]
|
8
|
+
def match_distance(others)
|
9
|
+
others.map { |c| [ c, distance(c) ] }.sort_by { |a| a[1] }
|
10
|
+
end
|
11
|
+
|
12
|
+
# Matches this color to a set of colors using the CIE 1976 delta E formula.
|
13
|
+
#
|
14
|
+
# Returns the given set of colors with their difference from this color, sorted by difference (nearest color first).
|
15
|
+
# @example Find the 3 nearest CSS named colors
|
16
|
+
# RGB.hex('f9c').match_de76(RGB.css).first(3)
|
17
|
+
def match_de76(others)
|
18
|
+
others.map { |c| [ c, de76(c) ] }.sort_by { |a| a[1] }
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
data/lib/redgreenblue/misc.rb
CHANGED
@@ -11,10 +11,16 @@ class RGB
|
|
11
11
|
dup.invert!
|
12
12
|
end
|
13
13
|
|
14
|
+
# Returns true when this is an achromatic color: red, green, and blue have equal values.
|
15
|
+
# Otherwise false.
|
16
|
+
def achromatic?
|
17
|
+
values.min == values.max
|
18
|
+
end
|
19
|
+
|
14
20
|
# Returns an array of RGB objects for all possible ways in which the red, green, and blue values of this object can be exchanged.
|
15
21
|
#
|
16
|
-
# Example: RGB.red.permutation returns [ RGB.red, RGB.green, RGB.blue ]
|
17
|
-
# See also: shuffle
|
22
|
+
# Example: RGB.red.permutation returns [ RGB.red, RGB.green, RGB.blue ].
|
23
|
+
# See also: shuffle.
|
18
24
|
def permutation
|
19
25
|
values.permutation.to_a.uniq.map { |v| RGB.new v }
|
20
26
|
end
|
@@ -24,4 +30,23 @@ class RGB
|
|
24
30
|
[ RGB.new(red,0,0), RGB.new(0,green,0), RGB.new(0,0,blue) ]
|
25
31
|
end
|
26
32
|
|
33
|
+
# Creates a new RGB object from three RGB objects representing the red, green, and blue components.
|
34
|
+
def self.assemble(*a)
|
35
|
+
v = a.flatten
|
36
|
+
RGB.new(v[0].red, v[1].green, v[2].blue)
|
37
|
+
end
|
38
|
+
|
39
|
+
# Returns the euclidean distance between this color and another color.
|
40
|
+
#
|
41
|
+
# When you imagine a color as a point in a 3-dimensional space,
|
42
|
+
# the dimensions being red, green, and blue,
|
43
|
+
# this is the distance between two colors.
|
44
|
+
def distance(another)
|
45
|
+
(
|
46
|
+
( (another.red - red ) ** 2) +
|
47
|
+
( (another.green - green) ** 2) +
|
48
|
+
( (another.blue - blue ) ** 2)
|
49
|
+
) ** (1/2.0)
|
50
|
+
end
|
51
|
+
|
27
52
|
end
|
data/lib/redgreenblue/mix.rb
CHANGED
@@ -16,9 +16,13 @@ class RGB
|
|
16
16
|
mix!(RGB.white, portion)
|
17
17
|
end
|
18
18
|
|
19
|
-
# Creates
|
20
|
-
def whiten(portion=0.5)
|
21
|
-
|
19
|
+
# Creates one or more new RGB objects by mixing this object's color with a portion of white.
|
20
|
+
def whiten(portion=0.5, *portions)
|
21
|
+
if (portion.class != Array) and portions.none?
|
22
|
+
mix(RGB.white, portion)
|
23
|
+
else
|
24
|
+
( [portion].flatten + portions ).map { |p| mix(RGB.white, p) }
|
25
|
+
end
|
22
26
|
end
|
23
27
|
|
24
28
|
# Changes the object's color by mixing it with a portion of black.
|
@@ -26,9 +30,26 @@ class RGB
|
|
26
30
|
mix!(RGB.black, portion)
|
27
31
|
end
|
28
32
|
|
29
|
-
# Creates
|
30
|
-
def blacken(portion=0.5)
|
31
|
-
|
33
|
+
# Creates one or more new RGB objects by mixing this object's color with a portion of black.
|
34
|
+
def blacken(portion=0.5, *portions)
|
35
|
+
if (portion.class != Array) and portions.none?
|
36
|
+
mix(RGB.black, portion)
|
37
|
+
else
|
38
|
+
( [portion].flatten + portions ).map { |p| mix(RGB.black, p) }
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# Returns a set of colors between this color and another. That other color is included.
|
43
|
+
#
|
44
|
+
# The resulting colors are spaced evenly in the RGB color space using a straightforward calculation.
|
45
|
+
# You will likely experience these colors as not exactly evenly spaced.
|
46
|
+
def steps(another,step_count=1,include_begin=false)
|
47
|
+
# origin (self, optional)
|
48
|
+
( include_begin ? [self.dup] : [] ) +
|
49
|
+
# ...plus intermediate colors
|
50
|
+
(1..step_count-1).map { |c| mix(another, c.to_f/step_count) } +
|
51
|
+
# ...plus destination color
|
52
|
+
[another.dup]
|
32
53
|
end
|
33
54
|
|
34
55
|
private
|
@@ -1,13 +1,28 @@
|
|
1
1
|
# Optional support for Philips Hue lights.
|
2
|
+
#
|
3
|
+
# Conforms to Bridge API 1.35 for Philips Hue, published 20-Nov-2019.
|
2
4
|
|
3
5
|
# Automatically load core RGB class before loading options.
|
4
6
|
require 'redgreenblue'
|
5
7
|
|
6
8
|
class RGB
|
7
9
|
|
8
|
-
#
|
10
|
+
# Only available when optional support for Philips Hue lights is loaded.
|
9
11
|
#
|
10
|
-
#
|
12
|
+
# Returns a hash with the arguments required by the Philips Hue API,
|
13
|
+
# to set a light to this RGB object's hue, saturation and brightness.
|
14
|
+
#
|
15
|
+
# Formatted as JSON, this hash can be sent to a bridge to set a light's state.
|
16
|
+
#
|
17
|
+
# See (regrettably requires registration):
|
18
|
+
# - https://developers.meethue.com/develop/hue-api/
|
19
|
+
#
|
20
|
+
# @example Load
|
21
|
+
# require 'redgreenblue/opt/philipshue'
|
22
|
+
# @example Use
|
23
|
+
# RGB.magenta.to_philips_hue_api_hsb_arguments
|
24
|
+
# => {"on"=>true, "bri"=>254, "hue"=>54613, "sat"=>254}
|
25
|
+
# @return [Hash] API arguments
|
11
26
|
def to_philips_hue_api_hsb_arguments(black_off=true)
|
12
27
|
my_hsb = hsb
|
13
28
|
|
data/lib/redgreenblue/os/mac.rb
CHANGED
@@ -1,17 +1,20 @@
|
|
1
1
|
class RGB
|
2
2
|
|
3
|
-
#
|
3
|
+
# On Mac OS, shows the color picker to choose a color for the RGB object.
|
4
|
+
# Not available on other platforms.
|
4
5
|
def pick
|
5
|
-
result = RGB.mac_choose(
|
6
|
+
result = RGB.mac_choose(self)
|
6
7
|
if result
|
7
8
|
self.rrggbb = result
|
8
9
|
end
|
9
10
|
end
|
10
11
|
|
11
|
-
#
|
12
|
+
# On Mac OS, shows the color picker and creates an RGB object with the chosen color.
|
13
|
+
# Not available on other platforms.
|
14
|
+
#
|
12
15
|
# If no default color is specified, the picker defaults to a middle grey.
|
13
16
|
def self.pick(default_color=RGB.new)
|
14
|
-
result = RGB.mac_choose(default_color
|
17
|
+
result = RGB.mac_choose(default_color)
|
15
18
|
if result
|
16
19
|
RGB.rrggbb result
|
17
20
|
else
|
@@ -29,7 +32,7 @@ class RGB
|
|
29
32
|
#
|
30
33
|
# Applescript command documented here:
|
31
34
|
# Standard Additions -> User Interaction -> choose color
|
32
|
-
def self.mac_choose(
|
35
|
+
def self.mac_choose(default_color)
|
33
36
|
|
34
37
|
app = case ENV['TERM_PROGRAM']
|
35
38
|
when /iTerm\.app/
|
@@ -41,7 +44,7 @@ class RGB
|
|
41
44
|
script = <<~ENDSCRIPT
|
42
45
|
tell application "#{app}"
|
43
46
|
try
|
44
|
-
return choose color default color
|
47
|
+
return choose color default color #{default_color.applescript}
|
45
48
|
on error
|
46
49
|
return ""
|
47
50
|
end try
|
@@ -0,0 +1,45 @@
|
|
1
|
+
class RGB
|
2
|
+
|
3
|
+
# Returns a new RGB object with this color's Ostwald full-color,
|
4
|
+
# or nil for achromatic colors (white, greys, and black).
|
5
|
+
#
|
6
|
+
# The resulting color contains no white or black,
|
7
|
+
# i.e. it has at least one RGB component set to 0, and at least one set to maximum.
|
8
|
+
#
|
9
|
+
# This is identical (barring very small rounding errors)
|
10
|
+
# to setting HSL-saturation to 1, and -lightness to 0.5
|
11
|
+
#
|
12
|
+
# Based on:
|
13
|
+
# - Color for the Sciences, pp. 575–591
|
14
|
+
# - https://lirias.kuleuven.be/retrieve/306124 (PDF)
|
15
|
+
def ostwald_color
|
16
|
+
white_portion = values.min
|
17
|
+
color_portion = values.max - white_portion
|
18
|
+
|
19
|
+
if color_portion == 0
|
20
|
+
nil
|
21
|
+
else
|
22
|
+
RGB.new( values.map { |v| ( ( v - white_portion ) / color_portion ).round(6) } )
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# Returns the portions of Ostwald full-color, white, and black, which constitute this color.
|
27
|
+
#
|
28
|
+
# The sum of these three numbers equals 1.
|
29
|
+
#
|
30
|
+
# #cwk is an alias for #ostwald_cwk.
|
31
|
+
#
|
32
|
+
# Based on:
|
33
|
+
# - Color for the Sciences, pp. 575–591
|
34
|
+
# - https://lirias.kuleuven.be/retrieve/306124 (PDF)
|
35
|
+
def ostwald_cwk
|
36
|
+
[
|
37
|
+
color_portion = values.max - values.min,
|
38
|
+
white_portion = values.min,
|
39
|
+
1 - color_portion - white_portion
|
40
|
+
]
|
41
|
+
end
|
42
|
+
|
43
|
+
alias cwk ostwald_cwk
|
44
|
+
|
45
|
+
end
|
@@ -0,0 +1,164 @@
|
|
1
|
+
GIMP Palette
|
2
|
+
Name: CSS Named Colors
|
3
|
+
#
|
4
|
+
# As per CSS Color Module Level 4, Editor's Draft, 19 August 2020.
|
5
|
+
# - source: https://drafts.csswg.org/css-color/#named-colors
|
6
|
+
#
|
7
|
+
# Notes:
|
8
|
+
# "Don't cite this document other than as work in progress."
|
9
|
+
#
|
10
|
+
# "CSS defines a large set of named colors, so that
|
11
|
+
# common colors can be written and read more easily."
|
12
|
+
#
|
13
|
+
# "[...] all of these keywords are ASCII case-insensitive."
|
14
|
+
#
|
15
|
+
# "The names resolve to colors in sRGB."
|
16
|
+
#
|
17
|
+
240 248 255 aliceblue
|
18
|
+
250 235 215 antiquewhite
|
19
|
+
0 255 255 aqua
|
20
|
+
127 255 212 aquamarine
|
21
|
+
240 255 255 azure
|
22
|
+
245 245 220 beige
|
23
|
+
255 228 196 bisque
|
24
|
+
0 0 0 black
|
25
|
+
255 235 205 blanchedalmond
|
26
|
+
0 0 255 blue
|
27
|
+
138 43 226 blueviolet
|
28
|
+
165 42 42 brown
|
29
|
+
222 184 135 burlywood
|
30
|
+
95 158 160 cadetblue
|
31
|
+
127 255 0 chartreuse
|
32
|
+
210 105 30 chocolate
|
33
|
+
255 127 80 coral
|
34
|
+
100 149 237 cornflowerblue
|
35
|
+
255 248 220 cornsilk
|
36
|
+
220 20 60 crimson
|
37
|
+
0 255 255 cyan
|
38
|
+
0 0 139 darkblue
|
39
|
+
0 139 139 darkcyan
|
40
|
+
184 134 11 darkgoldenrod
|
41
|
+
169 169 169 darkgray
|
42
|
+
0 100 0 darkgreen
|
43
|
+
169 169 169 darkgrey
|
44
|
+
189 183 107 darkkhaki
|
45
|
+
139 0 139 darkmagenta
|
46
|
+
85 107 47 darkolivegreen
|
47
|
+
255 140 0 darkorange
|
48
|
+
153 50 204 darkorchid
|
49
|
+
139 0 0 darkred
|
50
|
+
233 150 122 darksalmon
|
51
|
+
143 188 143 darkseagreen
|
52
|
+
72 61 139 darkslateblue
|
53
|
+
47 79 79 darkslategray
|
54
|
+
47 79 79 darkslategrey
|
55
|
+
0 206 209 darkturquoise
|
56
|
+
148 0 211 darkviolet
|
57
|
+
255 20 147 deeppink
|
58
|
+
0 191 255 deepskyblue
|
59
|
+
105 105 105 dimgray
|
60
|
+
105 105 105 dimgrey
|
61
|
+
30 144 255 dodgerblue
|
62
|
+
178 34 34 firebrick
|
63
|
+
255 250 240 floralwhite
|
64
|
+
34 139 34 forestgreen
|
65
|
+
255 0 255 fuchsia
|
66
|
+
220 220 220 gainsboro
|
67
|
+
248 248 255 ghostwhite
|
68
|
+
255 215 0 gold
|
69
|
+
218 165 32 goldenrod
|
70
|
+
128 128 128 gray
|
71
|
+
0 128 0 green
|
72
|
+
173 255 47 greenyellow
|
73
|
+
128 128 128 grey
|
74
|
+
240 255 240 honeydew
|
75
|
+
255 105 180 hotpink
|
76
|
+
205 92 92 indianred
|
77
|
+
75 0 130 indigo
|
78
|
+
255 255 240 ivory
|
79
|
+
240 230 140 khaki
|
80
|
+
230 230 250 lavender
|
81
|
+
255 240 245 lavenderblush
|
82
|
+
124 252 0 lawngreen
|
83
|
+
255 250 205 lemonchiffon
|
84
|
+
173 216 230 lightblue
|
85
|
+
240 128 128 lightcoral
|
86
|
+
224 255 255 lightcyan
|
87
|
+
250 250 210 lightgoldenrodyellow
|
88
|
+
211 211 211 lightgray
|
89
|
+
144 238 144 lightgreen
|
90
|
+
211 211 211 lightgrey
|
91
|
+
255 182 193 lightpink
|
92
|
+
255 160 122 lightsalmon
|
93
|
+
32 178 170 lightseagreen
|
94
|
+
135 206 250 lightskyblue
|
95
|
+
119 136 153 lightslategray
|
96
|
+
119 136 153 lightslategrey
|
97
|
+
176 196 222 lightsteelblue
|
98
|
+
255 255 224 lightyellow
|
99
|
+
0 255 0 lime
|
100
|
+
50 205 50 limegreen
|
101
|
+
250 240 230 linen
|
102
|
+
255 0 255 magenta
|
103
|
+
128 0 0 maroon
|
104
|
+
102 205 170 mediumaquamarine
|
105
|
+
0 0 205 mediumblue
|
106
|
+
186 85 211 mediumorchid
|
107
|
+
147 112 219 mediumpurple
|
108
|
+
60 179 113 mediumseagreen
|
109
|
+
123 104 238 mediumslateblue
|
110
|
+
0 250 154 mediumspringgreen
|
111
|
+
72 209 204 mediumturquoise
|
112
|
+
199 21 133 mediumvioletred
|
113
|
+
25 25 112 midnightblue
|
114
|
+
245 255 250 mintcream
|
115
|
+
255 228 225 mistyrose
|
116
|
+
255 228 181 moccasin
|
117
|
+
255 222 173 navajowhite
|
118
|
+
0 0 128 navy
|
119
|
+
253 245 230 oldlace
|
120
|
+
128 128 0 olive
|
121
|
+
107 142 35 olivedrab
|
122
|
+
255 165 0 orange
|
123
|
+
255 69 0 orangered
|
124
|
+
218 112 214 orchid
|
125
|
+
238 232 170 palegoldenrod
|
126
|
+
152 251 152 palegreen
|
127
|
+
175 238 238 paleturquoise
|
128
|
+
219 112 147 palevioletred
|
129
|
+
255 239 213 papayawhip
|
130
|
+
255 218 185 peachpuff
|
131
|
+
205 133 63 peru
|
132
|
+
255 192 203 pink
|
133
|
+
221 160 221 plum
|
134
|
+
176 224 230 powderblue
|
135
|
+
128 0 128 purple
|
136
|
+
102 51 153 rebeccapurple
|
137
|
+
255 0 0 red
|
138
|
+
188 143 143 rosybrown
|
139
|
+
65 105 225 royalblue
|
140
|
+
139 69 19 saddlebrown
|
141
|
+
250 128 114 salmon
|
142
|
+
244 164 96 sandybrown
|
143
|
+
46 139 87 seagreen
|
144
|
+
255 245 238 seashell
|
145
|
+
160 82 45 sienna
|
146
|
+
192 192 192 silver
|
147
|
+
135 206 235 skyblue
|
148
|
+
106 90 205 slateblue
|
149
|
+
112 128 144 slategray
|
150
|
+
112 128 144 slategrey
|
151
|
+
255 250 250 snow
|
152
|
+
0 255 127 springgreen
|
153
|
+
70 130 180 steelblue
|
154
|
+
210 180 140 tan
|
155
|
+
0 128 128 teal
|
156
|
+
216 191 216 thistle
|
157
|
+
255 99 71 tomato
|
158
|
+
64 224 208 turquoise
|
159
|
+
238 130 238 violet
|
160
|
+
245 222 179 wheat
|
161
|
+
255 255 255 white
|
162
|
+
245 245 245 whitesmoke
|
163
|
+
255 255 0 yellow
|
164
|
+
154 205 50 yellowgreen
|
data/lib/redgreenblue/rgb565.rb
CHANGED
@@ -15,11 +15,6 @@ class RGB
|
|
15
15
|
self.b = ( ( v & 0x001f ) ) << 3
|
16
16
|
end
|
17
17
|
|
18
|
-
# Returns the color in 16-bit RGB565 format as a string of 0's and 1's
|
19
|
-
def rgb565_binary
|
20
|
-
rgb565.bytes.reverse.map { |b| "%08b" % b }.join
|
21
|
-
end
|
22
|
-
|
23
18
|
# Creates a new RGB color from 16-bit RGB565 data.
|
24
19
|
def self.rgb565(rgb565_string)
|
25
20
|
c = self.new
|