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.
@@ -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