redgreenblue 0.17.0 → 0.19.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: 2359fa39f6387727f76770372b1f798ae60fdf34dce8bd481b06d58e5a128c4b
4
- data.tar.gz: 6194f07e51ce46a4c9bdd3fd7d2fd895eebcb8e6f34e76c37b3c078d3ea58fb9
3
+ metadata.gz: c8ae59f94eaf3e3cfb8fd8610b95d8f14cc05f9902e565b0cc587ad03e560bc1
4
+ data.tar.gz: f34de8f1025a07deb03c6de996f2875cc3d72212151432dcbb811fbfe5093fd7
5
5
  SHA512:
6
- metadata.gz: e76a1651bfac0b0f197cae93a9fa3139e798a3a2ab0ae00950d08eb5e724834f9ccce7fe06beb98b083988fd4d7b672431aee5c23a66c24cce2782669606b517
7
- data.tar.gz: 688367a83417deb0a812e96982f9c44ec369a1ee6984836338c25b07bd11843ced02053341044cebcaf2e4e71ce5ef26316799850831e446b85ece5766d31ddf
6
+ metadata.gz: eece5011d8efd21b6fd22eea58de73b2cb070f34093085049b61c847c8c88f462e4b79465222060bee5398cd5c7c5c80a9d3fb682c68dacaba017c8e6ca1a47c
7
+ data.tar.gz: 54eac4f2defd4841e5057c91308e0479ccb03a29d0645b9e0a6603d3ec479cdd96ac2369496d401d77a10dedb816d93f0cb6464edc95e6a76a2228535971ef29
@@ -1,90 +1,89 @@
1
- class RGB::Color
1
+ module RGB
2
2
 
3
- def initialize(*a)
4
- self.values = a.any? ? a : [ 0.5, 0.5, 0.5 ]
5
- end
3
+ class Color
6
4
 
7
- # Returns the color space.
8
- #
9
- # Currently always 'sRGB'.
10
- def color_space
11
- 'sRGB'
12
- end
5
+ def initialize(*a)
6
+ self.values = a.any? ? a : [ 0.5, 0.5, 0.5 ]
7
+ end
13
8
 
14
- # Returns the red component as a value between 0 and 1.
15
- def red
16
- @red
17
- end
9
+ # Returns the color space.
10
+ #
11
+ # Currently always 'sRGB'.
12
+ def color_space
13
+ 'sRGB'
14
+ end
18
15
 
19
- # Returns the green component as a value between 0 and 1.
20
- def green
21
- @green
22
- end
16
+ # Returns the red component as a value between 0 and 1.
17
+ def red
18
+ @red
19
+ end
23
20
 
24
- # Returns the blue component as a value between 0 and 1.
25
- def blue
26
- @blue
27
- end
21
+ # Returns the green component as a value between 0 and 1.
22
+ def green
23
+ @green
24
+ end
28
25
 
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)
34
- end
26
+ # Returns the blue component as a value between 0 and 1.
27
+ def blue
28
+ @blue
29
+ end
35
30
 
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
31
+ # Sets the red component to a value between 0 and 1.
32
+ #
33
+ # Values outside the range 0..1 will be clipped.
34
+ def red=(value)
35
+ @red = limit(value)
36
+ end
42
37
 
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
38
+ # Sets the green component to a value between 0 and 1.
39
+ #
40
+ # Values outside the range 0..1 will be clipped.
41
+ def green=(value)
42
+ @green = limit(value)
43
+ end
49
44
 
50
- # Returns the red, green, and blue components as three values between 0 and 1.
51
- def values
52
- [ red, green, blue ]
53
- end
45
+ # Sets the blue component to a value between 0 and 1.
46
+ #
47
+ # Values outside the range 0..1 will be clipped.
48
+ def blue=(value)
49
+ @blue = limit(value)
50
+ end
54
51
 
55
- alias to_a values
52
+ # Returns the red, green, and blue components as three values between 0 and 1.
53
+ def values
54
+ [ red, green, blue ]
55
+ end
56
56
 
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
57
+ alias to_a values
63
58
 
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
59
+ # Sets the red, green, and blue components using three values between 0 and 1.
60
+ #
61
+ # Values outside the range 0..1 will be clipped.
62
+ def values=(*a)
63
+ self.red, self.green, self.blue = a.flatten
64
+ end
68
65
 
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
75
- end
66
+ # Returns true if this object and another object represent exactly the same color. Otherwise returns false.
67
+ def ==(other)
68
+ ( self.class == other.class ) && ( self.values == other.values )
69
+ end
76
70
 
77
- private
71
+ # Returns a sorted hash of 3 key/value pairs for red, green, and blue,
72
+ # sorted in order of decreasing value.
73
+ def to_h
74
+ ([:red, :green, :blue].zip values).sort_by {
75
+ |k,v| [-v,[:red, :green, :blue].index(k)]
76
+ }.to_h
77
+ end
78
78
 
79
- # limits to range 0..1
80
- def limit(n)
81
- n <= 0 ? 0.0 : n >= 1 ? 1.0 : n
82
- end
79
+ private
83
80
 
84
- end
81
+ # limits to range 0..1
82
+ def limit(n)
83
+ n <= 0 ? 0.0 : n >= 1 ? 1.0 : n
84
+ end
85
85
 
86
- # The main namespace for redgreenblue.
87
- module RGB
86
+ end
88
87
 
89
88
  class << self
90
89
 
@@ -26,6 +26,17 @@ class RGB::Color
26
26
  _inspect_swatch + ( name ? ' ' + name : '' )
27
27
  end
28
28
 
29
+ def _inspect_wilhelm
30
+ _inspect_short +
31
+ if h = hsl_h
32
+ " (H:%7.3f %s \e[0m" % [h, ostwald_color.terminal_background]
33
+ else
34
+ ' (H: - '
35
+ end +
36
+ ' C:%5.3f W:%5.3f K:%5.3f)' % cwk +
37
+ ( name ? ' ' + name : '' )
38
+ end
39
+
29
40
  public
30
41
 
31
42
  # Returns a programmer-friendly representation of the object.
@@ -2,6 +2,17 @@ class RGB::Color
2
2
 
3
3
  private
4
4
 
5
+ # Returns shortest angle of travel (rotation)
6
+ # to move between 2 points on a circle.
7
+ #
8
+ # Some discussions here:
9
+ # - https://stackoverflow.com/questions/9505862/
10
+ # - https://stackoverflow.com/questions/7428718/
11
+ def angle_of_travel(source, destination)
12
+ angle = destination - source
13
+ (angle.abs > 180) ? (angle + (angle.negative? ? 360 : -360)) : angle
14
+ end
15
+
5
16
  def zip_add(a,b)
6
17
  a.zip(b).map { |ab| ( ab[0] || 0 ) + ab[1] }
7
18
  end
@@ -39,10 +39,9 @@ class RGB::Color
39
39
  end
40
40
  end
41
41
 
42
- # Returns a set of colors between this color and another. That other color is included.
42
+ # Returns a number of colors, gradually changing from this color to another color.
43
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.
44
+ # The resulting colors are spaced evenly in the RGB color space.
46
45
  def steps(another,step_count=1,include_begin=false)
47
46
  # origin (self, optional)
48
47
  ( include_begin ? [self.dup] : [] ) +
@@ -52,6 +51,22 @@ class RGB::Color
52
51
  [another.dup]
53
52
  end
54
53
 
54
+ # Returns a number of colors, gradually changing from this color to another color.
55
+ #
56
+ # The resulting colors are spaced evenly by their HSL values (hue, saturation, and lightness).
57
+ def steps_hsl(another,step_count=1,include_begin=false)
58
+ steps_hsx(another,step_count,include_begin, :hsl)
59
+ end
60
+
61
+ # Returns a number of colors, gradually changing from this color to another color.
62
+ #
63
+ # The resulting colors are spaced evenly by their HSV values (hue, saturation, and value).
64
+ def steps_hsv(another,step_count=1,include_begin=false)
65
+ steps_hsx(another,step_count,include_begin, :hsv)
66
+ end
67
+
68
+ alias steps_hsb steps_hsv
69
+
55
70
  private
56
71
 
57
72
  def mix_values(some_values, portion)
@@ -62,4 +77,25 @@ class RGB::Color
62
77
  ( blue * (1 - portion) ) + ( some_values[2] * portion )
63
78
  ]
64
79
  end
80
+
81
+ def steps_hsx(another,step_count=1,include_begin=false,type)
82
+ raise NotImplementedError unless [:hsl, :hsv].include? type
83
+ src_hsx = self.send(type)
84
+ dest_hsx = another.send(type)
85
+
86
+ # Take care of achromatic origin/destination
87
+ src_hsx[0] = ( dest_hsx[0] || 0 ) unless src_hsx[0]
88
+ dest_hsx[0] = ( src_hsx[0] || 0 ) unless dest_hsx[0]
89
+
90
+ step = [angle_of_travel(src_hsx[0], dest_hsx[0]), dest_hsx[1]-src_hsx[1], dest_hsx[2]-src_hsx[2] ].map { |v| v/step_count }
91
+
92
+ # origin (self, optional)
93
+ ( include_begin ? [self.dup] : [] ) +
94
+ # ...plus intermediate colors
95
+ (1..step_count-1).map { |c| RGB.send(type, zip_add(src_hsx, step.map { |v| v*c })) } +
96
+ # ...plus destination color
97
+ [another.dup]
98
+
99
+ end
100
+
65
101
  end
@@ -1,7 +1,7 @@
1
1
  module RGB
2
2
 
3
3
  # redgreenblue version.
4
- VERSION = '0.17.0'
4
+ VERSION = '0.19.0'
5
5
 
6
6
  # Returns RGB::VERSION.
7
7
  def self.version
@@ -0,0 +1,24 @@
1
+ require 'redgreenblue/base'
2
+
3
+ class RGB::Color
4
+
5
+ # Returns the color's YUV values.
6
+ #
7
+ # Based on:
8
+ # - http://www.martinreddy.net/gfx/faqs/colorconv.faq (section 6.1)
9
+ # - https://en.wikipedia.org/wiki/Y%E2%80%B2UV
10
+ def yuv(round: true)
11
+ [
12
+ red * 0.299 + green * 0.587 + blue * 0.114,
13
+ red * -0.147 + green * -0.289 + blue * 0.436,
14
+ red * 0.615 + green * -0.515 + blue * -0.100
15
+ ].map { |v| round ? v.round(6) : v }
16
+
17
+ # Wikipedia (2024-Aug-7)
18
+ # suggests slightly different factors for U and V:
19
+ #
20
+ # U = red * -0.14713 + green * -0.28886 + blue * 0.436
21
+ # V = red * 0.615 + green * -0.51499 + blue * -0.10001
22
+ end
23
+
24
+ end
data/lib/redgreenblue.rb CHANGED
@@ -20,30 +20,47 @@ module RGB
20
20
 
21
21
  end
22
22
 
23
- %w(
23
+ require 'redgreenblue/version'
24
24
 
25
- version
25
+ require 'redgreenblue/base'
26
26
 
27
- base
27
+ require 'redgreenblue/24bit'
28
+ require 'redgreenblue/48bit'
29
+ require 'redgreenblue/hex'
30
+ require 'redgreenblue/int'
28
31
 
29
- 24bit 48bit hex int
32
+ require 'redgreenblue/hsl'
33
+ require 'redgreenblue/hsv'
34
+ require 'redgreenblue/hsb'
30
35
 
31
- hsl hsv hsb
36
+ require 'redgreenblue/ostwald'
37
+ require 'redgreenblue/hwb'
32
38
 
33
- ostwald hwb
39
+ require 'redgreenblue/gamma'
34
40
 
35
- gamma
41
+ require 'redgreenblue/cie_1931'
42
+ require 'redgreenblue/cie_1976'
43
+ require 'redgreenblue/cie_1994'
36
44
 
37
- cie_1931 cie_1976 cie_1994
45
+ require 'redgreenblue/name'
38
46
 
39
- name
47
+ require 'redgreenblue/inspect'
48
+ require 'redgreenblue/view'
49
+ require 'redgreenblue/lazy'
40
50
 
41
- inspect view lazy
51
+ require 'redgreenblue/rgb565'
52
+ require 'redgreenblue/bgr24bit'
53
+ require 'redgreenblue/gif'
54
+ require 'redgreenblue/terminal'
55
+ require 'redgreenblue/web'
56
+ require 'redgreenblue/gpl'
57
+ require 'redgreenblue/mac'
42
58
 
43
- rgb565 bgr24bit gif terminal web gpl mac
59
+ require 'redgreenblue/yuv'
44
60
 
45
- match mix misc random
61
+ require 'redgreenblue/match'
62
+ require 'redgreenblue/mix'
63
+ require 'redgreenblue/misc'
64
+ require 'redgreenblue/random'
46
65
 
47
- os
48
-
49
- ).each { |m| require "redgreenblue/#{m}" }
66
+ require 'redgreenblue/os'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: redgreenblue
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.17.0
4
+ version: 0.19.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - lllist.eu
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-07-18 00:00:00.000000000 Z
11
+ date: 2024-08-07 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description:
14
14
  email:
@@ -53,6 +53,7 @@ files:
53
53
  - lib/redgreenblue/version.rb
54
54
  - lib/redgreenblue/view.rb
55
55
  - lib/redgreenblue/web.rb
56
+ - lib/redgreenblue/yuv.rb
56
57
  homepage: https://github.com/lllisteu/redgreenblue
57
58
  licenses:
58
59
  - MIT