redgreenblue 0.6.0 → 0.11.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 +17 -13
- data/lib/redgreenblue/24bit.rb +38 -5
- data/lib/redgreenblue/48bit.rb +12 -5
- data/lib/redgreenblue/base.rb +58 -12
- data/lib/redgreenblue/bgr24bit.rb +5 -5
- data/lib/redgreenblue/cie.rb +45 -0
- data/lib/redgreenblue/gamma.rb +44 -0
- data/lib/redgreenblue/gif.rb +3 -2
- data/lib/redgreenblue/gpl.rb +30 -0
- data/lib/redgreenblue/hex.rb +46 -15
- 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 +69 -0
- data/lib/redgreenblue/int.rb +22 -0
- data/lib/redgreenblue/lazy.rb +44 -2
- data/lib/redgreenblue/math.rb +9 -0
- data/lib/redgreenblue/misc.rb +20 -41
- data/lib/redgreenblue/mix.rb +65 -0
- data/lib/redgreenblue/opt/philipshue.rb +54 -0
- data/lib/redgreenblue/os/mac.rb +24 -10
- data/lib/redgreenblue/ostwald.rb +45 -0
- data/lib/redgreenblue/random.rb +11 -3
- data/lib/redgreenblue/rgb565.rb +9 -10
- data/lib/redgreenblue/terminal.rb +19 -0
- data/lib/redgreenblue/version.rb +9 -1
- data/lib/redgreenblue/web.rb +10 -0
- metadata +23 -6
- data/lib/redgreenblue/nice.rb +0 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dc4e866d75637857fb5a4b27b77829e20f488e321fa287b73a5d6d9c21d194a9
|
4
|
+
data.tar.gz: e3f9e875b0a8893bd21a6cd503702881833f54873557f84c4cf4776338294668
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 94b96125e65443d7ceb66cfabf9ba6b0681bfc51046b8d308e86d0904a58a7f745f6ea159a040ee79dcb9713ace9adbc416a5705c4b2ebb85333bf09f0dd9a43
|
7
|
+
data.tar.gz: f3e0bd4c0cdcd432dd50fc518f1d2062c66ac907f55b3235405589b2d797791c48b3d62284ae665a8fc4d60c4209ce0b3d46d07a459e15d2fa261d9b1aa8df1d
|
data/lib/redgreenblue.rb
CHANGED
@@ -1,22 +1,26 @@
|
|
1
1
|
class RGB
|
2
2
|
end
|
3
3
|
|
4
|
-
|
4
|
+
%w(
|
5
5
|
|
6
|
-
|
6
|
+
version
|
7
7
|
|
8
|
-
|
9
|
-
require 'redgreenblue/48bit'
|
10
|
-
require 'redgreenblue/hex'
|
8
|
+
base
|
11
9
|
|
12
|
-
|
13
|
-
require 'redgreenblue/nice'
|
10
|
+
24bit 48bit hex int
|
14
11
|
|
15
|
-
|
16
|
-
require 'redgreenblue/bgr24bit'
|
17
|
-
require 'redgreenblue/gif'
|
12
|
+
hsl hsv hsb
|
18
13
|
|
19
|
-
|
20
|
-
require 'redgreenblue/random'
|
14
|
+
ostwald
|
21
15
|
|
22
|
-
|
16
|
+
gamma cie
|
17
|
+
|
18
|
+
inspect lazy
|
19
|
+
|
20
|
+
rgb565 bgr24bit gif terminal web gpl
|
21
|
+
|
22
|
+
mix misc random
|
23
|
+
|
24
|
+
os
|
25
|
+
|
26
|
+
).each { |m| require "redgreenblue/#{m}" }
|
data/lib/redgreenblue/24bit.rb
CHANGED
@@ -2,46 +2,79 @@ class RGB
|
|
2
2
|
|
3
3
|
# r, g, b methods
|
4
4
|
|
5
|
+
# Returns the red component as an integer in the range 0..255 (an 8-bit value).
|
5
6
|
def r
|
6
7
|
(red * 255).round
|
7
8
|
end
|
8
9
|
|
10
|
+
# Returns the green component as an integer in the range 0..255 (an 8-bit value).
|
9
11
|
def g
|
10
12
|
(green * 255).round
|
11
13
|
end
|
12
14
|
|
15
|
+
# Returns the blue component as an integer in the range 0..255 (an 8-bit value).
|
13
16
|
def b
|
14
17
|
(blue * 255).round
|
15
18
|
end
|
16
19
|
|
20
|
+
# Sets the red component using an integer in the range 0..255 (an 8-bit value).
|
17
21
|
def r=(n)
|
18
22
|
self.red = n / 255.0
|
19
23
|
end
|
20
24
|
|
25
|
+
# Sets the green component using an integer in the range 0..255 (an 8-bit value).
|
21
26
|
def g=(n)
|
22
27
|
self.green = n / 255.0
|
23
28
|
end
|
24
29
|
|
30
|
+
# Sets the blue component using an integer in the range 0..255 (an 8-bit value).
|
25
31
|
def b=(n)
|
26
32
|
self.blue = n / 255.0
|
27
33
|
end
|
28
34
|
|
29
35
|
# rgb methods
|
30
36
|
|
37
|
+
# Returns the red, green, and blue components as integers in the range 0..255 (three 8-bit values).
|
31
38
|
def rgb
|
32
39
|
[r,g,b]
|
33
40
|
end
|
34
41
|
|
35
|
-
|
36
|
-
|
42
|
+
# Sets the red, green, and blue components using three integers in the range 0..255 (three 8-bit values).
|
43
|
+
def rgb=(*rgb)
|
44
|
+
self.r, self.g, self.b = rgb.flatten
|
37
45
|
end
|
38
46
|
|
39
|
-
#
|
40
|
-
|
41
|
-
def self.rgb(rgb)
|
47
|
+
# Creates a new object from red, green, and blue components as integers in the range 0..255 (three 8-bit values).
|
48
|
+
def self.rgb(*rgb)
|
42
49
|
c = self.new
|
43
50
|
c.rgb = rgb
|
44
51
|
c
|
45
52
|
end
|
46
53
|
|
54
|
+
# Sets the red, green, and blue values to those of the nearest 24-bit color.
|
55
|
+
def snap!
|
56
|
+
self.rgb = rgb
|
57
|
+
self
|
58
|
+
end
|
59
|
+
|
60
|
+
# Creates a new RGB object containing the nearest 24-bit color.
|
61
|
+
def snap
|
62
|
+
RGB.rgb rgb
|
63
|
+
end
|
64
|
+
|
65
|
+
# Calls the given block for each 24-bit RGB color (from black to white), passing the color as an RGB object.
|
66
|
+
#
|
67
|
+
# Returns the number of iterations.
|
68
|
+
def self.each_24bit_color
|
69
|
+
range = 0..255
|
70
|
+
range.each do |r|
|
71
|
+
range.each do |g|
|
72
|
+
range.each do |b|
|
73
|
+
yield self.rgb(r,g,b)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
range.size ** 3
|
78
|
+
end
|
79
|
+
|
47
80
|
end
|
data/lib/redgreenblue/48bit.rb
CHANGED
@@ -2,43 +2,50 @@ class RGB
|
|
2
2
|
|
3
3
|
# rr, gg, bb methods
|
4
4
|
|
5
|
+
# Returns the red component as an integer in the range 0..65535 (a 16-bit value).
|
5
6
|
def rr
|
6
7
|
(red * 65535).round
|
7
8
|
end
|
8
9
|
|
10
|
+
# Returns the green component as an integer in the range 0..65535 (a 16-bit value).
|
9
11
|
def gg
|
10
12
|
(green * 65535).round
|
11
13
|
end
|
12
14
|
|
15
|
+
# Returns the blue component as an integer in the range 0..65535 (a 16-bit value).
|
13
16
|
def bb
|
14
17
|
(blue * 65535).round
|
15
18
|
end
|
16
19
|
|
20
|
+
# Sets the red component using an integer in the range 0..65535 (a 16-bit value).
|
17
21
|
def rr=(n)
|
18
22
|
self.red = n / 65535.0
|
19
23
|
end
|
20
24
|
|
25
|
+
# Sets the green component using an integer in the range 0..65535 (a 16-bit value).
|
21
26
|
def gg=(n)
|
22
27
|
self.green = n / 65535.0
|
23
28
|
end
|
24
29
|
|
30
|
+
# Sets the blue component using an integer in the range 0..65535 (a 16-bit value).
|
25
31
|
def bb=(n)
|
26
32
|
self.blue = n / 65535.0
|
27
33
|
end
|
28
34
|
|
29
35
|
# rrggbb methods
|
30
36
|
|
37
|
+
# Returns the red, green, and blue components as integers in the range 0..65535 (three 16-bit values).
|
31
38
|
def rrggbb
|
32
39
|
[rr,gg,bb]
|
33
40
|
end
|
34
41
|
|
35
|
-
|
36
|
-
|
42
|
+
# Sets the red, green, and blue components using three integers in the range 0..65535 (three 16-bit values).
|
43
|
+
def rrggbb=(*rrggbb)
|
44
|
+
self.rr, self.gg, self.bb = rrggbb.flatten
|
37
45
|
end
|
38
46
|
|
39
|
-
#
|
40
|
-
|
41
|
-
def self.rrggbb(rrggbb)
|
47
|
+
# Creates a new object from red, green, and blue components as integers in the range 0..65535 (three 16-bit values).
|
48
|
+
def self.rrggbb(*rrggbb)
|
42
49
|
c = self.new
|
43
50
|
c.rrggbb = rrggbb
|
44
51
|
c
|
data/lib/redgreenblue/base.rb
CHANGED
@@ -1,36 +1,82 @@
|
|
1
1
|
class RGB
|
2
2
|
|
3
|
-
|
3
|
+
def initialize(*a)
|
4
|
+
self.values = a.any? ? a : [ 0.5, 0.5, 0.5 ]
|
5
|
+
end
|
6
|
+
|
7
|
+
# Returns the color space.
|
8
|
+
#
|
9
|
+
# Currently always 'sRGB'.
|
10
|
+
def color_space
|
11
|
+
@color_space ||= 'sRGB'
|
12
|
+
end
|
4
13
|
|
5
|
-
|
6
|
-
|
14
|
+
# Returns the red component as a value between 0 and 1.
|
15
|
+
def red
|
16
|
+
@red
|
7
17
|
end
|
8
18
|
|
9
|
-
|
10
|
-
|
19
|
+
# Returns the green component as a value between 0 and 1.
|
20
|
+
def green
|
21
|
+
@green
|
11
22
|
end
|
12
23
|
|
13
|
-
|
14
|
-
|
24
|
+
# Returns the blue component as a value between 0 and 1.
|
25
|
+
def blue
|
26
|
+
@blue
|
15
27
|
end
|
16
28
|
|
17
|
-
|
18
|
-
|
29
|
+
# Sets the red component to a value between 0 and 1.
|
30
|
+
#
|
31
|
+
# Values outside the range 0..1 will be clipped.
|
32
|
+
def red=(value)
|
33
|
+
@red = limit(value)
|
19
34
|
end
|
20
35
|
|
36
|
+
# Sets the green component to a value between 0 and 1.
|
37
|
+
#
|
38
|
+
# Values outside the range 0..1 will be clipped.
|
39
|
+
def green=(value)
|
40
|
+
@green = limit(value)
|
41
|
+
end
|
42
|
+
|
43
|
+
# Sets the blue component to a value between 0 and 1.
|
44
|
+
#
|
45
|
+
# Values outside the range 0..1 will be clipped.
|
46
|
+
def blue=(value)
|
47
|
+
@blue = limit(value)
|
48
|
+
end
|
49
|
+
|
50
|
+
# Returns the red, green, and blue components as three values between 0 and 1.
|
21
51
|
def values
|
22
52
|
[ red, green, blue ]
|
23
53
|
end
|
24
54
|
|
25
55
|
alias to_a values
|
26
56
|
|
27
|
-
|
28
|
-
|
57
|
+
# Sets the red, green, and blue components using three values between 0 and 1.
|
58
|
+
#
|
59
|
+
# Values outside the range 0..1 will be clipped.
|
60
|
+
def values=(*a)
|
61
|
+
self.red, self.green, self.blue = a.flatten
|
62
|
+
end
|
63
|
+
|
64
|
+
# Returns true if this object and another object represent exactly the same color. Otherwise returns false.
|
65
|
+
def ==(other)
|
66
|
+
( self.class == other.class ) && ( self.values == other.values )
|
67
|
+
end
|
68
|
+
|
69
|
+
# Returns a sorted hash of 3 key/value pairs for red, green, and blue,
|
70
|
+
# sorted in order of decreasing value.
|
71
|
+
def to_h
|
72
|
+
([:red, :green, :blue].zip values).sort_by {
|
73
|
+
|k,v| [-v,[:red, :green, :blue].index(k)]
|
74
|
+
}.to_h
|
29
75
|
end
|
30
76
|
|
31
77
|
private
|
32
78
|
|
33
|
-
#
|
79
|
+
# limits to range 0..1
|
34
80
|
def limit(n)
|
35
81
|
n <= 0 ? 0.0 : n >= 1 ? 1.0 : n
|
36
82
|
end
|
@@ -1,16 +1,16 @@
|
|
1
1
|
class RGB
|
2
2
|
|
3
|
-
#
|
4
|
-
|
3
|
+
# Returns a 3-byte string containing the object's color in BGR24 format.
|
5
4
|
def bgr24
|
6
5
|
[b, g, r].pack('C3')
|
7
6
|
end
|
8
7
|
|
9
|
-
|
10
|
-
|
8
|
+
# Sets red, green, and blue using BGR24 data (a 3-byte string).
|
9
|
+
def bgr24=(bgr_string)
|
10
|
+
self.b, self.g, self.r = bgr_string.unpack('C3')
|
11
11
|
end
|
12
12
|
|
13
|
-
#
|
13
|
+
# Creates a new RGB object from BGR24 data (a 3-byte string).
|
14
14
|
def self.bgr24(bgr)
|
15
15
|
c = self.new
|
16
16
|
c.bgr24 = bgr
|
@@ -0,0 +1,45 @@
|
|
1
|
+
class RGB
|
2
|
+
|
3
|
+
# Returns CIE 1931 XYZ values for the RGB object.
|
4
|
+
#
|
5
|
+
# Based on:
|
6
|
+
# - http://www.brucelindbloom.com/index.html?Eqn_RGB_to_XYZ.html
|
7
|
+
# - https://en.wikipedia.org/wiki/CIE_1931_color_space
|
8
|
+
# sRGB to XYZ matrix for D65 reference white by Bruce Lindbloom:
|
9
|
+
# - http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html
|
10
|
+
def cie_xyz
|
11
|
+
r, g, b = linear_values
|
12
|
+
[
|
13
|
+
r * 0.4124564 + g * 0.3575761 + b * 0.1804375,
|
14
|
+
r * 0.2126729 + g * 0.7151522 + b * 0.0721750,
|
15
|
+
r * 0.0193339 + g * 0.1191920 + b * 0.9503041
|
16
|
+
].map { |v| v.round(6) }
|
17
|
+
end
|
18
|
+
|
19
|
+
alias xyz cie_xyz
|
20
|
+
|
21
|
+
# Returns CIE 1931 xyY values for the RGB object.
|
22
|
+
#
|
23
|
+
# Based on:
|
24
|
+
# - https://en.wikipedia.org/wiki/CIE_1931_color_space
|
25
|
+
# - http://www.brucelindbloom.com/index.html?Eqn_XYZ_to_xyY.html
|
26
|
+
# - https://ninedegreesbelow.com/photography/xyz-rgb.html
|
27
|
+
def cie_xyy
|
28
|
+
x, y, z = xyz
|
29
|
+
[
|
30
|
+
x / ( x + y + z ),
|
31
|
+
y / ( x + y + z ),
|
32
|
+
y
|
33
|
+
].map { |v| v.round(6) }
|
34
|
+
end
|
35
|
+
|
36
|
+
alias xyy cie_xyy
|
37
|
+
|
38
|
+
# Returns CIE 1931 xy values for the RGB object.
|
39
|
+
def cie_xy
|
40
|
+
cie_xyy[0..1]
|
41
|
+
end
|
42
|
+
|
43
|
+
alias xy cie_xy
|
44
|
+
|
45
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
class RGB
|
2
|
+
|
3
|
+
# Returns gamma-expanded (inverse-companded) RGB values for the object (three values between 0 and 1).
|
4
|
+
#
|
5
|
+
# Based on:
|
6
|
+
# - https://en.wikipedia.org/wiki/SRGB
|
7
|
+
# - http://www.brucelindbloom.com/Eqn_RGB_to_XYZ.html
|
8
|
+
# - https://entropymine.com/imageworsener/srgbformula/
|
9
|
+
def linear_values
|
10
|
+
if color_space == 'sRGB'
|
11
|
+
values.map { |v|
|
12
|
+
if v <= 0.04045
|
13
|
+
v / 12.92
|
14
|
+
else
|
15
|
+
( ( v + 0.055 ) / 1.055 ) ** 2.4
|
16
|
+
end
|
17
|
+
}
|
18
|
+
else
|
19
|
+
raise "can not compute gamma for color space '#{color_space}'"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# Sets the object's RGB values using three linear RGB values, each between 0 and 1.
|
24
|
+
# Linear values will be converted to the object's gamma (gamma-companded).
|
25
|
+
#
|
26
|
+
# Based on:
|
27
|
+
# - https://en.wikipedia.org/wiki/SRGB
|
28
|
+
# - http://www.brucelindbloom.com/Eqn_XYZ_to_RGB.html
|
29
|
+
# - https://entropymine.com/imageworsener/srgbformula/
|
30
|
+
def linear_values=(*a)
|
31
|
+
if color_space == 'sRGB'
|
32
|
+
self.values = a.flatten.map { |v|
|
33
|
+
if v <= 0.0031308
|
34
|
+
v * 12.92
|
35
|
+
else
|
36
|
+
1.055 * ( v ** ( 1/2.4 ) ) - 0.055
|
37
|
+
end
|
38
|
+
}.map { |v| v.round(9) }
|
39
|
+
else
|
40
|
+
raise "can not compute gamma for color space '#{color_space}'"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
data/lib/redgreenblue/gif.rb
CHANGED
@@ -1,15 +1,16 @@
|
|
1
1
|
class RGB
|
2
2
|
|
3
|
-
#
|
3
|
+
# Returns a 1-pixel GIF image set to the color.
|
4
4
|
#
|
5
5
|
# With help from:
|
6
|
-
# -
|
6
|
+
# - https://www.perlmonks.org/?node_id=7974
|
7
7
|
def gif_pixel
|
8
8
|
"GIF89a\1\0\1\0\x90\0\0".b +
|
9
9
|
rgb.pack('C3') +
|
10
10
|
"\0\0\0,\0\0\0\0\1\0\1\0\0\x02\x02\x04\1\0;".b
|
11
11
|
end
|
12
12
|
|
13
|
+
# Writes a 1-pixel GIF image to a file.
|
13
14
|
def gif_pixel_write(file_path)
|
14
15
|
File.binwrite(file_path, gif_pixel)
|
15
16
|
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
class RGB
|
2
|
+
|
3
|
+
########################################################################
|
4
|
+
# Class methods #
|
5
|
+
########################################################################
|
6
|
+
|
7
|
+
class << self
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
# Reverse-engineered from:
|
12
|
+
# - https://github.com/GNOME/gimp/blob/5d79fba8238a27b8691556489898d33b3fa0dda0/app/core/gimppalette-load.c
|
13
|
+
def gpl_header(name, columns=nil)
|
14
|
+
"GIMP Palette\n" +
|
15
|
+
"Name: #{name}\n" +
|
16
|
+
( columns ? "Columns: #{columns}\n" : '' )
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
########################################################################
|
22
|
+
# Instance methods #
|
23
|
+
########################################################################
|
24
|
+
|
25
|
+
# Returns the color in the format used in .gpl files (Gimp color palettes). A name for the color is optional.
|
26
|
+
def gpl(name=nil)
|
27
|
+
( "%3d %3d %3d" % rgb ) + ( name ? "\t#{name}" : '' )
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|