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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1cac7c885ca1de3e3fe22ebfaf7207dd17b7bd25e8c1dd6f82cfdab0e0b5cee1
4
- data.tar.gz: 7ca71212d78ae2a638d8bfb54dcb8a824367eac6e7fe8ca1eaa1e239b22bbaa9
3
+ metadata.gz: dc4e866d75637857fb5a4b27b77829e20f488e321fa287b73a5d6d9c21d194a9
4
+ data.tar.gz: e3f9e875b0a8893bd21a6cd503702881833f54873557f84c4cf4776338294668
5
5
  SHA512:
6
- metadata.gz: 23316f3526690807fabde09d5a909ae7afe396da7b039baa6352c814ab653d02ee5646aa23ece364748cf090f4b9218a34c0cd19b8a04313086b2c5f9dcadf97
7
- data.tar.gz: 19f71a26312a83d845f8ff508758e653b693289be129e02281e65cb8da4b13d32ab5b58282883ea0d0dc4c156ddd775c0179354bea5dccc6065f00ad49b7f66c
6
+ metadata.gz: 94b96125e65443d7ceb66cfabf9ba6b0681bfc51046b8d308e86d0904a58a7f745f6ea159a040ee79dcb9713ace9adbc416a5705c4b2ebb85333bf09f0dd9a43
7
+ data.tar.gz: f3e0bd4c0cdcd432dd50fc518f1d2062c66ac907f55b3235405589b2d797791c48b3d62284ae665a8fc4d60c4209ce0b3d46d07a459e15d2fa261d9b1aa8df1d
@@ -1,22 +1,26 @@
1
1
  class RGB
2
2
  end
3
3
 
4
- require 'redgreenblue/version'
4
+ %w(
5
5
 
6
- require 'redgreenblue/base'
6
+ version
7
7
 
8
- require 'redgreenblue/24bit'
9
- require 'redgreenblue/48bit'
10
- require 'redgreenblue/hex'
8
+ base
11
9
 
12
- require 'redgreenblue/lazy'
13
- require 'redgreenblue/nice'
10
+ 24bit 48bit hex int
14
11
 
15
- require 'redgreenblue/rgb565'
16
- require 'redgreenblue/bgr24bit'
17
- require 'redgreenblue/gif'
12
+ hsl hsv hsb
18
13
 
19
- require 'redgreenblue/misc'
20
- require 'redgreenblue/random'
14
+ ostwald
21
15
 
22
- require 'redgreenblue/os'
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}" }
@@ -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
- def rgb=(rgb)
36
- self.r, self.g, self.b = rgb
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
- # factory method
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
@@ -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
- def rrggbb=(rrggbb)
36
- self.rr, self.gg, self.bb = rrggbb
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
- # factory method
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
@@ -1,36 +1,82 @@
1
1
  class RGB
2
2
 
3
- attr_reader :red, :green, :blue
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
- def initialize(a=[0.5, 0.5, 0.5])
6
- self.values = a
14
+ # Returns the red component as a value between 0 and 1.
15
+ def red
16
+ @red
7
17
  end
8
18
 
9
- def red=(n)
10
- @red = limit(n)
19
+ # Returns the green component as a value between 0 and 1.
20
+ def green
21
+ @green
11
22
  end
12
23
 
13
- def green=(n)
14
- @green = limit(n)
24
+ # Returns the blue component as a value between 0 and 1.
25
+ def blue
26
+ @blue
15
27
  end
16
28
 
17
- def blue=(n)
18
- @blue = limit(n)
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
- def values=(a)
28
- self.red, self.green, self.blue = a
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
- # limit to 0..1
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
- # bgr 24-bit methods (as used by BMP bitmaps)
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
- def bgr24=(s)
10
- self.b, self.g, self.r = s.unpack('C3')
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
- # factory method
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
@@ -1,15 +1,16 @@
1
1
  class RGB
2
2
 
3
- # Return a 1-pixel GIF
3
+ # Returns a 1-pixel GIF image set to the color.
4
4
  #
5
5
  # With help from:
6
- # - http://www.perlmonks.org/?node_id=7974
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