color_calculator 0.0.2 → 1.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3cb265697fa59d6dd79763755e743efeb50051c9
4
- data.tar.gz: bbd472be88da168b8dcc4a82f9bbbc936bf2bd93
3
+ metadata.gz: c07fc4c3003a07a1504d0814fa9d6de586750340
4
+ data.tar.gz: 7d3f50d42bc4e3e7455b7f568df58311f863f9b8
5
5
  SHA512:
6
- metadata.gz: 1193d2cb045d199418b1a6fad751797dac69f8e6a950731718da26b1febfaccbe61e6a442be3ece73489d649bf4709dd9ff342a89f38a60ad3c689566128411f
7
- data.tar.gz: 7a1d4432fc6257e7bc55698f2c1c3ed7b69216ef01ef722cb0dc8d3bd512dca93b9c7e694d6a5939af85e192bc9bac3f0e327a6bac67df8e5a51a88878ba9e90
6
+ metadata.gz: 7d4388fd40c9f0b7a199a791c30dd090e21c7e2fd287f42f88610e820a00f48f672aaef089a51e0779ecdd877f356b824465f57679ddc3342c7302e1ca430cce
7
+ data.tar.gz: ed5ff908d20a4b03739dd31fbd8f8add01e3127e6f190290f9b04969227cf5dba2d2e0d07f12d519cc2576f3efb3843b2ebe86b7b362c9b0a0d3345310a16974
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative '../clump/lab'
4
+ require_relative '../shared/constants'
4
5
 
5
6
  module ColorCalculator
6
7
  module Calculation
@@ -11,9 +12,6 @@ module ColorCalculator
11
12
  end
12
13
  end
13
14
 
14
- RADIANS_TO_DEGREES = 180.to_f / Math::PI
15
- DEGREES_TO_RADIANS = 1.to_f / RADIANS_TO_DEGREES
16
-
17
15
  K_OF_L = 1
18
16
  K_OF_C = 1
19
17
  K_OF_H = 1
@@ -65,7 +63,7 @@ module ColorCalculator
65
63
  [
66
64
  2,
67
65
  Math.sqrt(c_prime_reference * c_prime_sample),
68
- Math.sin(Rational(delta_little_h_prime, 2) * DEGREES_TO_RADIANS),
66
+ Math.sin(Rational(delta_little_h_prime, 2) * Constants::DEGREES_TO_RADIANS),
69
67
  ].reduce(:*)
70
68
  end
71
69
 
@@ -74,7 +72,7 @@ module ColorCalculator
74
72
  end
75
73
 
76
74
  def r_of_t
77
- -1 * Math.sin(2 * delta_theta * DEGREES_TO_RADIANS) * r_of_c
75
+ -1 * Math.sin(2 * delta_theta * Constants::DEGREES_TO_RADIANS) * r_of_c
78
76
  end
79
77
 
80
78
  %i[reference sample].each do |lab|
@@ -115,7 +113,10 @@ module ColorCalculator
115
113
  define_method("little_h_prime_#{lab}") do
116
114
  return 0 if [send(lab).beta, send("a_prime_#{lab}")].all? { |el| el == 0 }
117
115
 
118
- (Math.atan2(send(lab).beta, send("a_prime_#{lab}")) * RADIANS_TO_DEGREES) % 360
116
+ (
117
+ Math.atan2(send(lab).beta, send("a_prime_#{lab}")) *
118
+ Constants::RADIANS_TO_DEGREES
119
+ ) % 360
119
120
  end
120
121
  end
121
122
 
@@ -174,10 +175,10 @@ module ColorCalculator
174
175
  def big_t
175
176
  [
176
177
  1,
177
- -0.17 * Math.cos((little_h_bar_prime - 30) * DEGREES_TO_RADIANS),
178
- 0.24 * Math.cos(2 * little_h_bar_prime * DEGREES_TO_RADIANS),
179
- 0.32 * Math.cos((3 * little_h_bar_prime + 6) * DEGREES_TO_RADIANS),
180
- -0.2 * Math.cos((4 * little_h_bar_prime - 63) * DEGREES_TO_RADIANS),
178
+ -0.17 * Math.cos((little_h_bar_prime - 30) * Constants::DEGREES_TO_RADIANS),
179
+ 0.24 * Math.cos(2 * little_h_bar_prime * Constants::DEGREES_TO_RADIANS),
180
+ 0.32 * Math.cos((3 * little_h_bar_prime + 6) * Constants::DEGREES_TO_RADIANS),
181
+ -0.2 * Math.cos((4 * little_h_bar_prime - 63) * Constants::DEGREES_TO_RADIANS),
181
182
  ].reduce(:+)
182
183
  end
183
184
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  require_relative 'clump/abstract'
4
4
  require_relative 'clump/lab'
5
- require_relative 'clump/lch_ab'
5
+ require_relative 'clump/lch'
6
6
  require_relative 'clump/rgb'
7
7
  require_relative 'clump/xyz'
8
8
 
@@ -4,7 +4,7 @@ require_relative 'abstract'
4
4
 
5
5
  module ColorCalculator
6
6
  module Clump
7
- class LchAb < Abstract
7
+ class Lch < Abstract
8
8
  class << self
9
9
  def attributes
10
10
  %i[lightness chroma hue]
@@ -1,10 +1,48 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'conversion/lab_to_lch_ab'
3
+ require_relative 'conversion/lab_to_lch'
4
+ require_relative 'conversion/lab_to_xyz'
5
+ require_relative 'conversion/lch_to_lab'
6
+ require_relative 'conversion/rgb_to_lch'
4
7
  require_relative 'conversion/rgb_to_xyz'
5
- require_relative 'conversion/rgb_to_lch_ab'
6
8
  require_relative 'conversion/xyz_to_lab'
9
+ require_relative 'conversion/xyz_to_rgb'
7
10
 
8
11
  module ColorCalculator
9
- module Conversion; end
12
+ module Conversion
13
+ NOOP = -> (value) { value }
14
+
15
+ # Doesn't seem like it's worth it to build a proper graph for this yet.
16
+ # This map is fine, even if it is a bit repetitive.
17
+ MAP = {
18
+ lab: {
19
+ lab: NOOP,
20
+ lch: LabToLch.to_proc,
21
+ rgb: [LabToXyz, XyzToRgb].map(&:to_proc).reduce(:>>),
22
+ xyz: LabToXyz.to_proc
23
+ },
24
+ lch: {
25
+ lab: LchToLab.to_proc,
26
+ lch: NOOP,
27
+ rgb: [LchToLab, LabToXyz, XyzToRgb].map(&:to_proc).reduce(:>>),
28
+ xyz: [LchToLab, LabToXyz].map(&:to_proc).reduce(:>>)
29
+ },
30
+ rgb: {
31
+ lab: [RgbToXyz, XyzToLab].map(&:to_proc).reduce(:>>),
32
+ lch: [RgbToXyz, XyzToLab, LabToLch].map(&:to_proc).reduce(:>>),
33
+ rgb: NOOP,
34
+ xyz: RgbToXyz.to_proc
35
+ },
36
+ xyz: {
37
+ lab: XyzToLab.to_proc,
38
+ lch: [XyzToLab, LabToLch].map(&:to_proc).reduce(:>>),
39
+ rgb: XyzToRgb.to_proc,
40
+ xyz: NOOP
41
+ }
42
+ }
43
+
44
+ def self.build(from, to)
45
+ MAP[from][to]
46
+ end
47
+ end
10
48
  end
@@ -1,22 +1,21 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative '../clump/lab'
4
- require_relative '../clump/lch_ab'
4
+ require_relative '../clump/lch'
5
5
  require_relative '../shared/composable'
6
+ require_relative '../shared/constants'
6
7
 
7
8
  module ColorCalculator
8
9
  module Conversion
9
- class LabToLchAb
10
+ class LabToLch
10
11
  extend ColorCalculator::Composable
11
12
 
12
- RADIANS_TO_DEGREES = 180 / Math::PI
13
-
14
13
  def initialize(lab)
15
14
  @lab = lab
16
15
  end
17
16
 
18
17
  def call
19
- ColorCalculator::Clump::LchAb.new(lightness, chroma, hue)
18
+ ColorCalculator::Clump::Lch.new(lightness, chroma, hue)
20
19
  end
21
20
 
22
21
  private
@@ -32,7 +31,7 @@ module ColorCalculator
32
31
  end
33
32
 
34
33
  def hue
35
- val = Math.atan2(lab.beta, lab.alpha) * RADIANS_TO_DEGREES
34
+ val = Math.atan2(lab.beta, lab.alpha) * Constants::RADIANS_TO_DEGREES
36
35
 
37
36
  return val if val >= 0
38
37
 
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../clump/lab'
4
+ require_relative '../clump/xyz'
5
+ require_relative '../shared/composable'
6
+
7
+ module ColorCalculator
8
+ module Conversion
9
+ class LabToXyz
10
+ extend ColorCalculator::Composable
11
+
12
+ def initialize(lab)
13
+ @lab = lab
14
+ end
15
+
16
+ def call
17
+ Clump::Xyz.new(x, y, z)
18
+ end
19
+
20
+ private
21
+
22
+ attr_reader :lab
23
+
24
+ def x
25
+ x_of_r * Constants::D50.fetch(:x)
26
+ end
27
+
28
+ def y
29
+ y_of_r * Constants::D50.fetch(:y)
30
+ end
31
+
32
+ def z
33
+ z_of_r * Constants::D50.fetch(:z)
34
+ end
35
+
36
+ def f_of_x
37
+ Rational(lab.alpha, 500) + f_of_y
38
+ end
39
+
40
+ def f_of_y
41
+ Rational(lab.lightness + 16, 116)
42
+ end
43
+
44
+ def f_of_z
45
+ f_of_y - Rational(lab.beta, 200)
46
+ end
47
+
48
+ def x_of_r
49
+ val = f_of_x ** 3
50
+ return val if val > Constants::EPSILON
51
+
52
+ Rational(116 * f_of_x - 16, Constants::KAPPA)
53
+ end
54
+
55
+ def y_of_r
56
+ if lab.lightness > (Constants::KAPPA * Constants::EPSILON)
57
+ return Rational(Rational(lab.lightness + 16, 116)) ** 3
58
+ end
59
+
60
+ Rational(lab.lightness, Constants::KAPPA)
61
+ end
62
+
63
+ def z_of_r
64
+ val = f_of_z ** 3
65
+ return val if val > Constants::EPSILON
66
+
67
+ Rational(116 * f_of_z - 16, Constants::KAPPA)
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../clump/lab'
4
+ require_relative '../clump/lch'
5
+ require_relative '../shared/composable'
6
+ require_relative '../shared/constants'
7
+
8
+ module ColorCalculator
9
+ module Conversion
10
+ class LchToLab
11
+ extend Composable
12
+
13
+ def initialize(lch)
14
+ @lch = lch
15
+ end
16
+
17
+ def call
18
+ Clump::Lab.new(lightness, alpha, beta)
19
+ end
20
+
21
+ private
22
+
23
+ attr_reader :lch
24
+
25
+ def lightness
26
+ lch.lightness
27
+ end
28
+
29
+ def alpha
30
+ lch.chroma * Math.cos(lch.hue * Constants::DEGREES_TO_RADIANS)
31
+ end
32
+
33
+ def beta
34
+ lch.chroma * Math.sin(lch.hue * Constants::DEGREES_TO_RADIANS)
35
+ end
36
+ end
37
+ end
38
+ end
@@ -3,11 +3,11 @@
3
3
  require_relative '../shared/composable'
4
4
  require_relative '../conversion/rgb_to_xyz'
5
5
  require_relative '../conversion/xyz_to_lab'
6
- require_relative '../conversion/lab_to_lch_ab'
6
+ require_relative '../conversion/lab_to_lch'
7
7
 
8
8
  module ColorCalculator
9
9
  module Conversion
10
- class RgbToLchAb
10
+ class RgbToLch
11
11
  extend ColorCalculator::Composable
12
12
 
13
13
  def initialize(rgb)
@@ -30,7 +30,7 @@ module ColorCalculator
30
30
  [
31
31
  ColorCalculator::Conversion::RgbToXyz,
32
32
  ColorCalculator::Conversion::XyzToLab,
33
- ColorCalculator::Conversion::LabToLchAb
33
+ ColorCalculator::Conversion::LabToLch
34
34
  ]
35
35
  end
36
36
  end
@@ -3,26 +3,23 @@
3
3
  require_relative '../clump/lab'
4
4
  require_relative '../clump/xyz'
5
5
  require_relative '../shared/composable'
6
+ require_relative '../shared/constants'
6
7
 
7
8
  module ColorCalculator
8
9
  module Conversion
9
10
  class XyzToLab
10
11
  extend ColorCalculator::Composable
11
12
 
12
- D50 = { x: 0.964220, y: 1.000000, z: 0.825210 }
13
- EPSILON = 0.008856
14
- KAPPA = 903.3
15
-
16
13
  APPLE = -> (value) do
17
14
  value ** Rational(1, 3)
18
15
  end
19
16
 
20
17
  BANANA = -> (value) do
21
- ((KAPPA * value) + 16) / 116
18
+ ((Constants::KAPPA * value) + 16) / 116
22
19
  end
23
20
 
24
21
  FRUIT = -> (value) do
25
- (value > EPSILON ? APPLE : BANANA).call(value)
22
+ (value > Constants::EPSILON ? APPLE : BANANA).call(value)
26
23
  end
27
24
 
28
25
  def initialize(xyz)
@@ -51,7 +48,7 @@ module ColorCalculator
51
48
 
52
49
  %i[x y z].each do |symbol|
53
50
  define_method("#{symbol}_scaled") do
54
- xyz.public_send(symbol) / D50.fetch(symbol)
51
+ xyz.public_send(symbol) / Constants::D50.fetch(symbol)
55
52
  end
56
53
  end
57
54
  end
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../clump/rgb'
4
+ require_relative '../clump/xyz'
5
+
6
+ require_relative '../shared/composable'
7
+ require_relative '../shared/constants'
8
+
9
+ module ColorCalculator
10
+ module Conversion
11
+ class XyzToRgb
12
+ extend ColorCalculator::Composable
13
+
14
+ XYZ_TO_RGB_TRANSFORM_D50 = [
15
+ [3.1338561, -1.6168667, -0.4906146],
16
+ [-0.9787684, 1.9161415, 0.0334540],
17
+ [0.0719453, -0.2289914, 1.4052427]
18
+ ]
19
+
20
+ RGB_COMPAND = -> (value) do
21
+ if value <= 0.0031308
22
+ 12.92 * value
23
+ else
24
+ 1.055 * (value ** Rational(10, 24)) - 0.055
25
+ end
26
+ end
27
+
28
+ def initialize(xyz)
29
+ @xyz = xyz
30
+ end
31
+
32
+ def call
33
+ Clump::Rgb.new(red, green, blue, normalized: true)
34
+ end
35
+
36
+ private
37
+
38
+ attr_reader :xyz
39
+
40
+ def red
41
+ RGB_COMPAND.call(linear_rgb.fetch(:red))
42
+ end
43
+
44
+ def green
45
+ RGB_COMPAND.call(linear_rgb.fetch(:green))
46
+ end
47
+
48
+ def blue
49
+ RGB_COMPAND.call(linear_rgb.fetch(:blue))
50
+ end
51
+
52
+ def linear_rgb
53
+ Hash[
54
+ %i[red green blue].zip(
55
+ XYZ_TO_RGB_TRANSFORM_D50.map do |row|
56
+ %i[x y z].map.with_index do |xyz_val, index|
57
+ row[index] * xyz.public_send(xyz_val)
58
+ end.sum
59
+ end
60
+ )
61
+ ]
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ColorCalculator
4
+ module Constants
5
+ RADIANS_TO_DEGREES = Rational(180, Math::PI)
6
+
7
+ DEGREES_TO_RADIANS = Rational(Math::PI, 180)
8
+
9
+ D50 = { x: 0.964220, y: 1.000000, z: 0.825210 }
10
+
11
+ EPSILON = 0.008856
12
+
13
+ KAPPA = 903.3
14
+ end
15
+ end
@@ -3,5 +3,5 @@
3
3
  require_relative '../color_calculator'
4
4
 
5
5
  module ColorCalculator
6
- VERSION = '0.0.2'
6
+ VERSION = '1.1.0'
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: color_calculator
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nathan Seither
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-03-04 00:00:00.000000000 Z
11
+ date: 2020-03-06 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: You can do color math now!
14
14
  email:
@@ -25,15 +25,19 @@ files:
25
25
  - lib/color_calculator/clump.rb
26
26
  - lib/color_calculator/clump/abstract.rb
27
27
  - lib/color_calculator/clump/lab.rb
28
- - lib/color_calculator/clump/lch_ab.rb
28
+ - lib/color_calculator/clump/lch.rb
29
29
  - lib/color_calculator/clump/rgb.rb
30
30
  - lib/color_calculator/clump/xyz.rb
31
31
  - lib/color_calculator/conversion.rb
32
- - lib/color_calculator/conversion/lab_to_lch_ab.rb
33
- - lib/color_calculator/conversion/rgb_to_lch_ab.rb
32
+ - lib/color_calculator/conversion/lab_to_lch.rb
33
+ - lib/color_calculator/conversion/lab_to_xyz.rb
34
+ - lib/color_calculator/conversion/lch_to_lab.rb
35
+ - lib/color_calculator/conversion/rgb_to_lch.rb
34
36
  - lib/color_calculator/conversion/rgb_to_xyz.rb
35
37
  - lib/color_calculator/conversion/xyz_to_lab.rb
38
+ - lib/color_calculator/conversion/xyz_to_rgb.rb
36
39
  - lib/color_calculator/shared/composable.rb
40
+ - lib/color_calculator/shared/constants.rb
37
41
  - lib/color_calculator/version.rb
38
42
  homepage: https://github.com/Supernats/color_calculator
39
43
  licenses: