color_calculator 0.0.2 → 1.1.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
  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: