redgreenblue 0.7.0 → 0.12.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,22 @@
1
+ class RGB
2
+
3
+ # Returns the color as a 24-bit integer in the range 0..16777215.
4
+ def to_i
5
+ ( r << 16 ) + ( g << 8 ) + b
6
+ end
7
+
8
+ # Creates a new RGB object from a 24-bit integer in the range 0..16777215.
9
+ def self.at(number)
10
+ n = number.to_i
11
+ if (0..16777215) === n
12
+ rgb(
13
+ ( n & 0xff0000 ) >> 16,
14
+ ( n & 0x00ff00 ) >> 8,
15
+ ( n & 0x0000ff )
16
+ )
17
+ else
18
+ raise ArgumentError, "Argument '#{number}' not in range 0..16777215"
19
+ end
20
+ end
21
+
22
+ end
@@ -35,4 +35,19 @@ class RGB
35
35
  new(0,0,1)
36
36
  end
37
37
 
38
+ # Creates a yellow RGB object.
39
+ def self.yellow
40
+ new(1,1,0)
41
+ end
42
+
43
+ # Creates a cyan RGB object.
44
+ def self.cyan
45
+ new(0,1,1)
46
+ end
47
+
48
+ # Creates a magenta RGB object.
49
+ def self.magenta
50
+ new(1,0,1)
51
+ end
52
+
38
53
  end
@@ -0,0 +1,9 @@
1
+ class RGB
2
+
3
+ private
4
+
5
+ def zip_add(a,b)
6
+ a.zip(b).map { |ab| ( ab[0] || 0 ) + ab[1] }
7
+ end
8
+
9
+ end
@@ -1,60 +1,52 @@
1
1
  class RGB
2
2
 
3
- # Mix
4
-
5
- # Mix with second RGB color.
6
- # p denotes portion of the mixed-in color to be used.
7
- # p=0 delivers pure original color (no change),
8
- # p=1 delivers pure mixed-in color.
9
-
10
- def mix!(color,p=0.5)
11
- self.values = mix_values(color.values, p)
12
- self
13
- end
14
-
15
- def mix(color,p=0.5)
16
- RGB.new mix_values(color.values, p)
17
- end
18
-
19
- # Invert
20
-
3
+ # Inverts the object's color.
21
4
  def invert!
22
- self.values = values.map { |v| 1-v }
5
+ self.values = values.map { |v| 1 - v }
23
6
  self
24
7
  end
25
8
 
9
+ # Creates a new RGB object with the inverted color of this RGB object.
26
10
  def invert
27
11
  dup.invert!
28
12
  end
29
13
 
30
- # Mix with white
31
-
32
- def whiten!(p)
33
- mix!(RGB.white, p)
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
34
18
  end
35
19
 
36
- def whiten(p)
37
- mix(RGB.white, p)
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.
21
+ #
22
+ # Example: RGB.red.permutation returns [ RGB.red, RGB.green, RGB.blue ].
23
+ # See also: shuffle.
24
+ def permutation
25
+ values.permutation.to_a.uniq.map { |v| RGB.new v }
38
26
  end
39
27
 
40
- # Mix with black
41
-
42
- def blacken!(p)
43
- mix!(RGB.black, p)
28
+ # Returns an array of three RGB objects, for the red, green, and blue components of this object.
29
+ def components
30
+ [ RGB.new(red,0,0), RGB.new(0,green,0), RGB.new(0,0,blue) ]
44
31
  end
45
32
 
46
- def blacken(p)
47
- mix(RGB.black, p)
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)
48
37
  end
49
38
 
50
- private
51
-
52
- def mix_values(v, p)
53
- raise(ArgumentError, "Portion '#{p}' not in range (0..1)") unless (0..1).include? p
54
- [
55
- ( red * (1-p) ) + ( v[0] * p ),
56
- ( green * (1-p) ) + ( v[1] * p ),
57
- ( blue * (1-p) ) + ( v[2] * p )
58
- ]
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)
59
50
  end
51
+
60
52
  end
@@ -0,0 +1,65 @@
1
+ class RGB
2
+
3
+ # Changes the object's color by mixing it with a portion of another RGB color.
4
+ def mix!(another,portion=0.5)
5
+ self.values = mix_values(another.values, portion)
6
+ self
7
+ end
8
+
9
+ # Creates a new RGB object by mixing this object's color with a portion of another RGB color.
10
+ def mix(another,portion=0.5)
11
+ RGB.new mix_values(another.values, portion)
12
+ end
13
+
14
+ # Changes the object's color by mixing it with a portion of white.
15
+ def whiten!(portion=0.5)
16
+ mix!(RGB.white, portion)
17
+ end
18
+
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
26
+ end
27
+
28
+ # Changes the object's color by mixing it with a portion of black.
29
+ def blacken!(portion=0.5)
30
+ mix!(RGB.black, portion)
31
+ end
32
+
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]
53
+ end
54
+
55
+ private
56
+
57
+ def mix_values(some_values, portion)
58
+ raise(ArgumentError, "Portion '#{portion}' not in range (0..1)") unless (0..1).include? portion
59
+ [
60
+ ( red * (1 - portion) ) + ( some_values[0] * portion ),
61
+ ( green * (1 - portion) ) + ( some_values[1] * portion ),
62
+ ( blue * (1 - portion) ) + ( some_values[2] * portion )
63
+ ]
64
+ end
65
+ end
@@ -0,0 +1,13 @@
1
+ class RGB
2
+
3
+ # Returns the name.
4
+ def name
5
+ defined?(@name) ? @name : nil
6
+ end
7
+
8
+ # Sets the name (a string or nil).
9
+ def name=(text)
10
+ @name = ( text.to_s.size != 0 ) ? text.to_s : nil
11
+ end
12
+
13
+ end
@@ -1,9 +1,28 @@
1
+ # Optional support for Philips Hue lights.
2
+ #
3
+ # Conforms to Bridge API 1.35 for Philips Hue, published 20-Nov-2019.
4
+
5
+ # Automatically load core RGB class before loading options.
6
+ require 'redgreenblue'
7
+
1
8
  class RGB
2
9
 
3
- # Returns the arguments required by the Philips Hue API to set a light to this RGB object's hue, saturation and brightness (HSB).
10
+ # Only available when optional support for Philips Hue lights is loaded.
11
+ #
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/
4
19
  #
5
- # When formatted as JSON, this hash can be used
6
- # directly to set a light's state.
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
7
26
  def to_philips_hue_api_hsb_arguments(black_off=true)
8
27
  my_hsb = hsb
9
28
 
@@ -1,6 +1,7 @@
1
1
  class RGB
2
2
 
3
- # Shows the Mac OS color picker to choose a color for the RGB object.
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
6
  result = RGB.mac_choose(rrggbb)
6
7
  if result
@@ -8,7 +9,9 @@ class RGB
8
9
  end
9
10
  end
10
11
 
11
- # Shows the Mac OS color picker and creates an RGB object with the chosen color.
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
17
  result = RGB.mac_choose(default_color.rrggbb)
@@ -31,8 +34,15 @@ class RGB
31
34
  # Standard Additions -> User Interaction -> choose color
32
35
  def self.mac_choose(color)
33
36
 
37
+ app = case ENV['TERM_PROGRAM']
38
+ when /iTerm\.app/
39
+ 'iTerm'
40
+ else
41
+ 'Terminal'
42
+ end
43
+
34
44
  script = <<~ENDSCRIPT
35
- tell application "Terminal"
45
+ tell application "#{app}"
36
46
  try
37
47
  return choose color default color { #{color[0]}, #{color[1]}, #{color[2]} }
38
48
  on error
@@ -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