redgreenblue 0.6.0 → 0.11.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|