red-colors 0.1.1 → 0.1.2
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 +4 -4
- data/README.md +2 -0
- data/lib/colors.rb +1 -0
- data/lib/colors/convert.rb +45 -0
- data/lib/colors/rgb.rb +4 -0
- data/lib/colors/version.rb +1 -1
- data/lib/colors/xterm256.rb +56 -0
- data/lib/colors/xyz.rb +1 -1
- data/test/test-rgb.rb +60 -0
- data/test/test-xterm256.rb +76 -0
- metadata +11 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c144d5d89c917428d99401b92513852896b2ff109228d85b2ddac5dd40b89fb4
|
4
|
+
data.tar.gz: 8e99f5fadc2068211a0ec92d12ad754ae777efedd23048867c0ad91824fe7a35
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 53491ee2e2c97a99c624d5e4d2fc73d9939f68ee9b27f24f54bcf1f3831f87f8cf2d115d4c8b0499e73e2623ad6e045c714f254a4dc33da55dfdf84213b45903
|
7
|
+
data.tar.gz: 1d783343d7536ca570bdbd049d83d92a107450341e03a8f4a390f88abc891d92d67404e198b87ee7555b6abea05610e13f4afcd9421d417c20f1ef3e38be002c
|
data/README.md
CHANGED
data/lib/colors.rb
CHANGED
data/lib/colors/convert.rb
CHANGED
@@ -148,6 +148,51 @@ module Colors
|
|
148
148
|
dot_product(RGB2XYZ, srgb_to_linear_srgb(r, g, b))
|
149
149
|
end
|
150
150
|
|
151
|
+
def rgb_to_xterm256(r, g, b)
|
152
|
+
i = closest_xterm256_rgb_index(r)
|
153
|
+
j = closest_xterm256_rgb_index(g)
|
154
|
+
k = closest_xterm256_rgb_index(b)
|
155
|
+
|
156
|
+
r0 = xterm256_rgb_index_to_rgb_value(i)
|
157
|
+
g0 = xterm256_rgb_index_to_rgb_value(j)
|
158
|
+
b0 = xterm256_rgb_index_to_rgb_value(k)
|
159
|
+
d0 = (r - r0)**2 + (g - g0)**2 + (b - b0)**2
|
160
|
+
|
161
|
+
l = closest_xterm256_gray_index(r, g, b)
|
162
|
+
gr = xterm256_gray_index_to_gray_level(l)
|
163
|
+
d1 = (r - gr)**2 + (g - gr)**2 + (b - gr)**2
|
164
|
+
|
165
|
+
if d0 > d1
|
166
|
+
xterm256_gray_index_to_code(l)
|
167
|
+
else
|
168
|
+
xterm256_rgb_indices_to_code(i, j, k)
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
def xterm256_rgb_index_to_rgb_value(i)
|
173
|
+
(i == 0) ? 0 : (40*i + 55)/255.0
|
174
|
+
end
|
175
|
+
|
176
|
+
def closest_xterm256_rgb_index(x)
|
177
|
+
([x*255 - 55, 0].max / 40.0).round
|
178
|
+
end
|
179
|
+
|
180
|
+
def xterm256_gray_index_to_gray_level(i)
|
181
|
+
(10*i + 8)/255.0
|
182
|
+
end
|
183
|
+
|
184
|
+
def closest_xterm256_gray_index(r, g, b)
|
185
|
+
((255*(r + g + b) - 24)/30.0).round.clamp(0, 23)
|
186
|
+
end
|
187
|
+
|
188
|
+
def xterm256_rgb_indices_to_code(i, j, k)
|
189
|
+
6*(6*i + j) + k + 16
|
190
|
+
end
|
191
|
+
|
192
|
+
def xterm256_gray_index_to_code(i)
|
193
|
+
i + 232
|
194
|
+
end
|
195
|
+
|
151
196
|
# sRGB -> ???
|
152
197
|
|
153
198
|
def srgb_to_linear_srgb(r, g, b)
|
data/lib/colors/rgb.rb
CHANGED
@@ -125,6 +125,10 @@ module Colors
|
|
125
125
|
XYZ.new(*Convert.rgb_to_xyz(r, g, b))
|
126
126
|
end
|
127
127
|
|
128
|
+
def to_xterm256
|
129
|
+
Xterm256.new(*Convert.rgb_to_xterm256(r, g, b))
|
130
|
+
end
|
131
|
+
|
128
132
|
private def canonicalize(r, g, b)
|
129
133
|
if [r, g, b].map(&:class) == [Integer, Integer, Integer]
|
130
134
|
canonicalize_from_integer(r, g, b)
|
data/lib/colors/version.rb
CHANGED
@@ -0,0 +1,56 @@
|
|
1
|
+
module Colors
|
2
|
+
class Xterm256 < AbstractColor
|
3
|
+
include Helper
|
4
|
+
|
5
|
+
def initialize(code)
|
6
|
+
unless 16 <= code && code <= 255
|
7
|
+
raise ArgumentError, "code should be in 16..255, but #{code} is given"
|
8
|
+
end
|
9
|
+
@code = code
|
10
|
+
end
|
11
|
+
|
12
|
+
attr_reader :code
|
13
|
+
|
14
|
+
def ==(other)
|
15
|
+
case other
|
16
|
+
when Xterm256
|
17
|
+
code == other.code
|
18
|
+
else
|
19
|
+
super
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def to_rgb_components
|
24
|
+
if code < 232
|
25
|
+
x = code - 16
|
26
|
+
x, b = x.divmod(6)
|
27
|
+
r, g = x.divmod(6)
|
28
|
+
r = 40*r + 55 if r > 0
|
29
|
+
g = 40*g + 55 if g > 0
|
30
|
+
b = 40*b + 55 if b > 0
|
31
|
+
[
|
32
|
+
canonicalize_component_from_integer(r, :r),
|
33
|
+
canonicalize_component_from_integer(g, :r),
|
34
|
+
canonicalize_component_from_integer(b, :r)
|
35
|
+
]
|
36
|
+
else
|
37
|
+
grey = to_grey_level
|
38
|
+
[grey, grey, grey]
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def to_grey_level
|
43
|
+
if code < 232
|
44
|
+
r, g, b = to_rgb_components
|
45
|
+
x, y, z = Convet.rgb_to_xyz(r, g, b)
|
46
|
+
else
|
47
|
+
grey = 10*(code - 232) + 8
|
48
|
+
canonicalize_component_from_integer(grey, :grey)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def to_rgb
|
53
|
+
RGB.new(*to_rgb_components)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
data/lib/colors/xyz.rb
CHANGED
data/test/test-rgb.rb
CHANGED
@@ -318,4 +318,64 @@ class ColorsRGBTest < Test::Unit::TestCase
|
|
318
318
|
assert_near(Colors::HUSL.new(0r, 0r, 1r),
|
319
319
|
Colors::RGB.new(1r, 1r, 1r).to_husl)
|
320
320
|
end
|
321
|
+
|
322
|
+
data do
|
323
|
+
data_set = {}
|
324
|
+
# colors 16-231 are a 6x6x6 color cube
|
325
|
+
(0...6).each do |r|
|
326
|
+
(0...6).each do |g|
|
327
|
+
(0...6).each do |b|
|
328
|
+
code = 6*(6*r + g) + b + 16
|
329
|
+
red = (r > 0) ? 40*r + 55 : r
|
330
|
+
green = (g > 0) ? 40*g + 55 : g
|
331
|
+
blue = (b > 0) ? 40*b + 55 : b
|
332
|
+
label = "Color #{code} is rgb(#{red}, #{green}, #{blue})"
|
333
|
+
data_set[label] = [code, Colors::RGB.new(red, green, blue)]
|
334
|
+
end
|
335
|
+
end
|
336
|
+
end
|
337
|
+
# colors 232-256 are grayscale colors
|
338
|
+
(0...24).each do |y|
|
339
|
+
code = 232 + y
|
340
|
+
level = 10*y + 8
|
341
|
+
label = "Color #{code} is gray(#{level})"
|
342
|
+
data_set[label] = [code, Colors::RGB.new(level, level, level)]
|
343
|
+
end
|
344
|
+
# Some colors to check cloest color finder
|
345
|
+
[
|
346
|
+
[ 0, 0, 8, 16 ],
|
347
|
+
[ 0, 8, 0, 16 ],
|
348
|
+
[ 11, 0, 0, 16 ],
|
349
|
+
[ 0, 0, 12, 232 ],
|
350
|
+
[ 0, 12, 0, 232 ],
|
351
|
+
[ 12, 0, 0, 232 ],
|
352
|
+
|
353
|
+
[ 0, 0, 75, 17 ],
|
354
|
+
[ 0, 75, 0, 22 ],
|
355
|
+
[ 75, 0, 0, 52 ],
|
356
|
+
|
357
|
+
[ 0, 128, 128, 30 ],
|
358
|
+
[ 102, 102, 102, 241 ],
|
359
|
+
[ 103, 103, 103, 242 ],
|
360
|
+
[ 208, 238, 238, 254 ],
|
361
|
+
[ 208, 208, 238, 189 ],
|
362
|
+
|
363
|
+
# TODO: Reconsider the following cases
|
364
|
+
[ 0, 0, 55, 233 ],
|
365
|
+
[ 0, 55, 0, 233 ],
|
366
|
+
[ 55, 0, 0, 233 ],
|
367
|
+
[ 0, 0, 74, 234 ],
|
368
|
+
[ 0, 74, 0, 234 ],
|
369
|
+
[ 74, 0, 0, 234 ],
|
370
|
+
].each do |r, g, b, code|
|
371
|
+
label = "rgb(#{r}, #{g}, #{b}) is color #{code}"
|
372
|
+
data_set[label] = [code, Colors::RGB.new(r, g, b)]
|
373
|
+
end
|
374
|
+
data_set
|
375
|
+
end
|
376
|
+
def test_to_xterm256
|
377
|
+
code, rgb = data
|
378
|
+
assert_equal(Colors::Xterm256.new(code),
|
379
|
+
rgb.to_xterm256)
|
380
|
+
end
|
321
381
|
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
class ColorsXterm256Test < Test::Unit::TestCase
|
2
|
+
include TestHelper
|
3
|
+
|
4
|
+
sub_test_case(".new") do
|
5
|
+
sub_test_case("with color code") do
|
6
|
+
test("the regular case") do
|
7
|
+
codes = [16, 255]
|
8
|
+
colors = codes.map {|i| Colors::Xterm256.new(i) }
|
9
|
+
assert_equal(codes,
|
10
|
+
colors.map(&:code))
|
11
|
+
end
|
12
|
+
|
13
|
+
data do
|
14
|
+
(0..15).map { |code|
|
15
|
+
["ANSI color #{code}", code]
|
16
|
+
}.to_h
|
17
|
+
end
|
18
|
+
def test_ansi_color_code(code)
|
19
|
+
assert_raise(ArgumentError) do
|
20
|
+
Colors::Xterm256.new(code)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
test("the negative argument") do
|
25
|
+
assert_raise(ArgumentError) do
|
26
|
+
Colors::Xterm256.new(-1)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
test("too large argument") do
|
31
|
+
assert_raise(ArgumentError) do
|
32
|
+
Colors::Xterm256.new(256)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
test("==") do
|
39
|
+
assert { Colors::Xterm256.new(16) == Colors::Xterm256.new(16) }
|
40
|
+
assert { Colors::Xterm256.new(132) == Colors::Xterm256.new(132) }
|
41
|
+
end
|
42
|
+
|
43
|
+
test("!=") do
|
44
|
+
assert { Colors::Xterm256.new(16) != Colors::Xterm256.new(17) }
|
45
|
+
end
|
46
|
+
|
47
|
+
data do
|
48
|
+
data_set = {}
|
49
|
+
# colors 16-231 are a 6x6x6 color cube
|
50
|
+
(0...6).each do |r|
|
51
|
+
(0...6).each do |g|
|
52
|
+
(0...6).each do |b|
|
53
|
+
code = 6*(6*r + g) + b + 16
|
54
|
+
red = (r > 0) ? 40*r + 55 : r
|
55
|
+
green = (g > 0) ? 40*g + 55 : g
|
56
|
+
blue = (b > 0) ? 40*b + 55 : b
|
57
|
+
label = "Color #{code} is rgb(#{red}, #{green}, #{blue})"
|
58
|
+
data_set[label] = [code, Colors::RGB.new(red, green, blue)]
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
# colors 232-256 are grayscale colors
|
63
|
+
(0...24).each do |y|
|
64
|
+
code = 232 + y
|
65
|
+
level = 10*y + 8
|
66
|
+
label = "Color #{code} is gray(#{level})"
|
67
|
+
data_set[label] = [code, Colors::RGB.new(level, level, level)]
|
68
|
+
end
|
69
|
+
data_set
|
70
|
+
end
|
71
|
+
def test_to_rgb(data)
|
72
|
+
code, rgb = data
|
73
|
+
assert_equal(rgb,
|
74
|
+
Colors::Xterm256.new(code).to_rgb)
|
75
|
+
end
|
76
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: red-colors
|
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
|
- Kenta Murata
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-05-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -105,6 +105,7 @@ files:
|
|
105
105
|
- lib/colors/rgb.rb
|
106
106
|
- lib/colors/rgba.rb
|
107
107
|
- lib/colors/version.rb
|
108
|
+
- lib/colors/xterm256.rb
|
108
109
|
- lib/colors/xyy.rb
|
109
110
|
- lib/colors/xyz.rb
|
110
111
|
- red-colors.gemspec
|
@@ -116,6 +117,7 @@ files:
|
|
116
117
|
- test/test-named-color.rb
|
117
118
|
- test/test-rgb.rb
|
118
119
|
- test/test-rgba.rb
|
120
|
+
- test/test-xterm256.rb
|
119
121
|
- test/test-xyz.rb
|
120
122
|
homepage: https://github.com/red-data-tools/red-colors
|
121
123
|
licenses:
|
@@ -136,19 +138,19 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
136
138
|
- !ruby/object:Gem::Version
|
137
139
|
version: '0'
|
138
140
|
requirements: []
|
139
|
-
|
140
|
-
rubygems_version: 2.7.6.2
|
141
|
+
rubygems_version: 3.2.3
|
141
142
|
signing_key:
|
142
143
|
specification_version: 4
|
143
144
|
summary: Red Colors provides a wide array of features for dealing with colors. This
|
144
145
|
includes conversion between colorspaces, desaturation, and parsing colors.
|
145
146
|
test_files:
|
146
|
-
- test/test-hsla.rb
|
147
|
-
- test/test-named-color.rb
|
148
|
-
- test/test-rgba.rb
|
149
147
|
- test/helper.rb
|
150
|
-
- test/test-rgb.rb
|
151
148
|
- test/run.rb
|
152
149
|
- test/test-hsl.rb
|
153
|
-
- test/test-
|
150
|
+
- test/test-hsla.rb
|
154
151
|
- test/test-husl.rb
|
152
|
+
- test/test-named-color.rb
|
153
|
+
- test/test-rgb.rb
|
154
|
+
- test/test-rgba.rb
|
155
|
+
- test/test-xterm256.rb
|
156
|
+
- test/test-xyz.rb
|