redgreenblue 0.8.0 → 0.13.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,8 @@
1
+ class RGB
2
+
3
+ # Returns the color in the format used by AppleScript (a 48-bit RGB triplet).
4
+ def applescript
5
+ "{%i, %i, %i}" % rrggbb
6
+ end
7
+
8
+ end
@@ -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
@@ -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
@@ -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
@@ -16,9 +16,13 @@ class RGB
16
16
  mix!(RGB.white, portion)
17
17
  end
18
18
 
19
- # Creates a new RGB object by mixing this object's color with a portion of white.
20
- def whiten(portion=0.5)
21
- mix(RGB.white, portion)
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 a new RGB object by mixing this object's color with a portion of black.
30
- def blacken(portion=0.5)
31
- mix(RGB.black, portion)
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
@@ -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,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
- # 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.
9
11
  #
10
- # When formatted as JSON, this hash can be used directly to set a light's state.
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
 
@@ -1,17 +1,20 @@
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
- result = RGB.mac_choose(rrggbb)
6
+ result = RGB.mac_choose(self)
6
7
  if result
7
8
  self.rrggbb = result
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
- result = RGB.mac_choose(default_color.rrggbb)
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(color)
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 { #{color[0]}, #{color[1]}, #{color[2]} }
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
@@ -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
@@ -1,3 +1,11 @@
1
1
  class RGB
2
- VERSION = '0.8.0'
2
+
3
+ # redgreenblue version.
4
+ VERSION = '0.13.0'
5
+
6
+ # Returns RGB::VERSION.
7
+ def self.version
8
+ VERSION
9
+ end
10
+
3
11
  end