colorspace 0.1.0 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +3 -0
- data/Gemfile.lock +3 -1
- data/colorspace.gemspec +1 -2
- data/lib/colorspace/colorlib.rb +175 -0
- data/lib/colorspace/version.rb +1 -1
- data/lib/colorspace.rb +1 -0
- metadata +17 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9400e62857f08e86defabffe2f88ae73dc05ac5f05cc29f575a86917a2121c45
|
4
|
+
data.tar.gz: 8e38f06fc5d6d804a2cb81bcc3dbc0e2176987f9c7890088d62809998b1bcc73
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6abdcfa05487d616ad1972ac847bbc38744ceda59fd203b46327db3f3e7a7b162f8b2b201335c0d4f23dde49a05828f3fbbcf51d9358a82267b0ae20d2ad9969
|
7
|
+
data.tar.gz: e6e3d20acac710720d55f0e5d42fc9b7e32ee61c8eab857a24211ccd0e12224bbff7591d4a5a6d02c628d82dd56e73fce3cb0f5bb8a04ee9a9307dc5d41edfc7
|
data/.rubocop.yml
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
colorspace (0.1.
|
4
|
+
colorspace (0.1.1)
|
5
|
+
matrix (~> 0.4)
|
5
6
|
|
6
7
|
GEM
|
7
8
|
remote: https://rubygems.org/
|
@@ -9,6 +10,7 @@ GEM
|
|
9
10
|
ast (2.4.2)
|
10
11
|
json (2.7.1)
|
11
12
|
language_server-protocol (3.17.0.3)
|
13
|
+
matrix (0.4.2)
|
12
14
|
minitest (5.20.0)
|
13
15
|
parallel (1.24.0)
|
14
16
|
parser (3.2.2.4)
|
data/colorspace.gemspec
CHANGED
@@ -33,7 +33,6 @@ Gem::Specification.new do |spec|
|
|
33
33
|
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
34
34
|
spec.require_paths = ['lib']
|
35
35
|
|
36
|
-
|
37
|
-
# spec.add_dependency "example-gem", "~> 1.0"
|
36
|
+
spec.add_dependency 'matrix', '~> 0.4'
|
38
37
|
# spec.metadata['rubygems_mfa_required'] = 'true'
|
39
38
|
end
|
@@ -0,0 +1,175 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'matrix'
|
4
|
+
|
5
|
+
# Library for working with RGB, XYZ, and LAB colorspaces
|
6
|
+
module Colorspace
|
7
|
+
# rubocop: disable Layout/SpaceInsideArrayLiteralBrackets
|
8
|
+
# rubocop: disable Layout/ExtraSpacing
|
9
|
+
RGB_XYZ_MATRIX = Matrix[
|
10
|
+
[ 0.4124564, 0.3575761, 0.1804375 ],
|
11
|
+
[ 0.2126729, 0.7151522, 0.0721750 ],
|
12
|
+
[ 0.0193339, 0.1191920, 0.9503041 ]
|
13
|
+
].freeze
|
14
|
+
|
15
|
+
XYZ_RGB_MATRIX = Matrix[
|
16
|
+
[ 3.2404542, -1.5371385, -0.4985314 ],
|
17
|
+
[ -0.9692660, 1.8760108, 0.0415560 ],
|
18
|
+
[ 0.0556434, -0.2040259, 1.0572252 ]
|
19
|
+
].freeze
|
20
|
+
# rubocop: enable Layout/ExtraSpacing
|
21
|
+
# rubocop: enable Layout/SpaceInsideArrayLiteralBrackets
|
22
|
+
|
23
|
+
##
|
24
|
+
# A tristimulus value in the CIE 1931 space.
|
25
|
+
class XYZTristimulus < Data.define(:x, :y, :z)
|
26
|
+
# @dynamic x, y, z, initialize
|
27
|
+
|
28
|
+
def to_srgb_linear
|
29
|
+
r, g, b = (XYZ_RGB_MATRIX * Matrix[[x], [y], [z]]).to_a.flatten
|
30
|
+
|
31
|
+
SRGBLinearColor.new(r:, g:, b:)
|
32
|
+
end
|
33
|
+
|
34
|
+
def to_srgb
|
35
|
+
to_srgb_linear.gamma_compress
|
36
|
+
end
|
37
|
+
|
38
|
+
private def scale_f(val)
|
39
|
+
delta = 6.0 / 29
|
40
|
+
t = val
|
41
|
+
|
42
|
+
if t > delta**3
|
43
|
+
t**(1.0 / 3)
|
44
|
+
else
|
45
|
+
(t / (3 * (delta**2))) + (4.0 / 29)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# rubocop: disable Metrics/AbcSize
|
50
|
+
def to_cielab(illuminant: D65)
|
51
|
+
x_, y_, z_ = x * 100, y * 100, z * 100
|
52
|
+
xn, yn, zn = illuminant.x, illuminant.y, illuminant.z
|
53
|
+
|
54
|
+
l = (116 * scale_f(y_ / yn)) - 16
|
55
|
+
a = 500 * (scale_f(x_ / xn) - scale_f(y_ / yn))
|
56
|
+
b = 200 * (scale_f(y_ / yn) - scale_f(z_ / zn))
|
57
|
+
|
58
|
+
CIELABColor.new(l:, a:, b:)
|
59
|
+
end
|
60
|
+
# rubocop: enable Metrics/AbcSize
|
61
|
+
|
62
|
+
def to_ary = [x, y, z]
|
63
|
+
def to_a = to_ary
|
64
|
+
end
|
65
|
+
|
66
|
+
D65 = XYZTristimulus.new(x: 95.047, y: 100.0, z: 108.883)
|
67
|
+
D50 = XYZTristimulus.new(x: 96.42, y: 100.0, z: 82.51)
|
68
|
+
|
69
|
+
##
|
70
|
+
# An RGB value in the sRGB colorspace.
|
71
|
+
class SRGBColor < Data.define(:r, :g, :b)
|
72
|
+
# @dynamic r, g, b, initialize
|
73
|
+
def self.from_hex(hex)
|
74
|
+
r, g, b = hex.chars.last(6).each_slice(2)
|
75
|
+
.map { |c| c.join.to_i(16) / 255.0 }
|
76
|
+
|
77
|
+
new(r: r || 0.0, g: g || 0.0, b: b || 0.0)
|
78
|
+
end
|
79
|
+
|
80
|
+
def to_hex
|
81
|
+
[r, g, b].map { |val|
|
82
|
+
(val * 255).round.clamp(0, 255).to_s(16).rjust(2, '0')
|
83
|
+
}.join
|
84
|
+
end
|
85
|
+
|
86
|
+
private def gamma_expand_one(val)
|
87
|
+
if val <= 0.04045
|
88
|
+
val / 12.92
|
89
|
+
else
|
90
|
+
((val + 0.055) / 1.055)**2.4
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def to_xyz
|
95
|
+
gamma_expand.to_xyz
|
96
|
+
end
|
97
|
+
|
98
|
+
def gamma_expand
|
99
|
+
SRGBLinearColor.new(
|
100
|
+
r: gamma_expand_one(r),
|
101
|
+
g: gamma_expand_one(g),
|
102
|
+
b: gamma_expand_one(b)
|
103
|
+
)
|
104
|
+
end
|
105
|
+
|
106
|
+
def to_ary = [r, g, b]
|
107
|
+
def to_a = to_ary
|
108
|
+
end
|
109
|
+
|
110
|
+
##
|
111
|
+
# A gamma-expanded ("linear light") RGB value in the sRGB colorspace.
|
112
|
+
class SRGBLinearColor < Data.define(:r, :g, :b)
|
113
|
+
def to_xyz
|
114
|
+
x, y, z = (RGB_XYZ_MATRIX * Matrix[[r], [g], [b]]).to_a.flatten
|
115
|
+
XYZTristimulus.new(x:, y:, z:)
|
116
|
+
end
|
117
|
+
|
118
|
+
private def gamma_compress_one(val)
|
119
|
+
if val <= 0.0031308
|
120
|
+
12.92 * val
|
121
|
+
else
|
122
|
+
(1.055 * (val**(1.0 / 2.4))) - 0.055
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
def gamma_compress
|
127
|
+
SRGBColor.new(
|
128
|
+
r: gamma_compress_one(r),
|
129
|
+
g: gamma_compress_one(g),
|
130
|
+
b: gamma_compress_one(b)
|
131
|
+
)
|
132
|
+
end
|
133
|
+
|
134
|
+
def to_ary = [r, g, b]
|
135
|
+
def to_a = to_ary
|
136
|
+
end
|
137
|
+
|
138
|
+
##
|
139
|
+
# A color in the CIE LAB color space.
|
140
|
+
class CIELABColor < Data.define(:l, :a, :b)
|
141
|
+
def self.from_hex(...)
|
142
|
+
SRGBColor.from_hex(...).to_xyz.to_cielab
|
143
|
+
end
|
144
|
+
|
145
|
+
def to_hex
|
146
|
+
to_xyz.to_srgb.to_hex
|
147
|
+
end
|
148
|
+
|
149
|
+
# rubocop: disable Metrics/AbcSize
|
150
|
+
def to_xyz(illuminant: D65)
|
151
|
+
xn, yn, zn = illuminant.x, illuminant.y, illuminant.z
|
152
|
+
|
153
|
+
p = (l + 16) / 116.0
|
154
|
+
|
155
|
+
x = xn * ((p + (a / 500.0))**3) / 100.0
|
156
|
+
y = yn * (p**3) / 100.0
|
157
|
+
z = zn * ((p - (b / 200.0))**3) / 100.0
|
158
|
+
|
159
|
+
XYZTristimulus.new(x:, y:, z:)
|
160
|
+
end
|
161
|
+
# rubocop: enable Metrics/AbcSize
|
162
|
+
|
163
|
+
def cie76(other)
|
164
|
+
(((other.l - l)**2) + ((other.a - a)**2) + ((other.b - b)**2))**0.5
|
165
|
+
end
|
166
|
+
|
167
|
+
def ciede2000(other)
|
168
|
+
# TODO: write this
|
169
|
+
cie76(other)
|
170
|
+
end
|
171
|
+
|
172
|
+
def to_ary = [l, a, b]
|
173
|
+
def to_a = to_ary
|
174
|
+
end
|
175
|
+
end
|
data/lib/colorspace/version.rb
CHANGED
data/lib/colorspace.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: colorspace
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Anna Kudriavtsev
|
@@ -9,7 +9,21 @@ autorequire:
|
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
11
|
date: 1980-01-01 00:00:00.000000000 Z
|
12
|
-
dependencies:
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: matrix
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0.4'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0.4'
|
13
27
|
description:
|
14
28
|
email:
|
15
29
|
- anna328p@gmail.com
|
@@ -29,6 +43,7 @@ files:
|
|
29
43
|
- flake.lock
|
30
44
|
- flake.nix
|
31
45
|
- lib/colorspace.rb
|
46
|
+
- lib/colorspace/colorlib.rb
|
32
47
|
- lib/colorspace/version.rb
|
33
48
|
- shell.nix
|
34
49
|
- sig/colorspace.rbs
|