abachrome 0.1.5 → 0.2.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 +4 -4
- data/abachrome.gemspec +1 -0
- data/devenv.nix +1 -1
- data/lib/abachrome/abc_decimal.rb +42 -35
- data/lib/abachrome/color.rb +61 -10
- data/lib/abachrome/color_mixins/blend.rb +7 -5
- data/lib/abachrome/color_mixins/harmonies.rb +187 -0
- data/lib/abachrome/color_mixins/lighten.rb +8 -6
- data/lib/abachrome/color_mixins/spectral_mix.rb +70 -0
- data/lib/abachrome/color_mixins/to_colorspace.rb +10 -8
- data/lib/abachrome/color_mixins/to_grayscale.rb +87 -0
- data/lib/abachrome/color_mixins/to_lms.rb +106 -0
- data/lib/abachrome/color_mixins/to_lrgb.rb +14 -12
- data/lib/abachrome/color_mixins/to_oklab.rb +16 -14
- data/lib/abachrome/color_mixins/to_oklch.rb +12 -10
- data/lib/abachrome/color_mixins/to_srgb.rb +17 -15
- data/lib/abachrome/color_mixins/to_xyz.rb +106 -0
- data/lib/abachrome/color_mixins/wcag.rb +126 -0
- data/lib/abachrome/color_models/cmyk.rb +160 -0
- data/lib/abachrome/color_models/hsv.rb +5 -3
- data/lib/abachrome/color_models/lms.rb +3 -1
- data/lib/abachrome/color_models/oklab.rb +3 -1
- data/lib/abachrome/color_models/oklch.rb +6 -4
- data/lib/abachrome/color_models/rgb.rb +4 -2
- data/lib/abachrome/color_models/xyz.rb +11 -1
- data/lib/abachrome/color_models/yiq.rb +37 -0
- data/lib/abachrome/color_space.rb +28 -14
- data/lib/abachrome/converter.rb +10 -8
- data/lib/abachrome/converters/base.rb +13 -11
- data/lib/abachrome/converters/cmyk_to_srgb.rb +42 -0
- data/lib/abachrome/converters/lms_to_lrgb.rb +5 -3
- data/lib/abachrome/converters/lms_to_oklab.rb +28 -0
- data/lib/abachrome/converters/lms_to_srgb.rb +6 -4
- data/lib/abachrome/converters/lms_to_xyz.rb +5 -3
- data/lib/abachrome/converters/lrgb_to_lms.rb +29 -1
- data/lib/abachrome/converters/lrgb_to_oklab.rb +5 -3
- data/lib/abachrome/converters/lrgb_to_srgb.rb +6 -4
- data/lib/abachrome/converters/lrgb_to_xyz.rb +5 -3
- data/lib/abachrome/converters/oklab_to_lms.rb +9 -7
- data/lib/abachrome/converters/oklab_to_lrgb.rb +7 -7
- data/lib/abachrome/converters/oklab_to_oklch.rb +4 -2
- data/lib/abachrome/converters/oklab_to_srgb.rb +4 -2
- data/lib/abachrome/converters/oklab_to_xyz.rb +29 -0
- data/lib/abachrome/converters/oklch_to_lms.rb +28 -0
- data/lib/abachrome/converters/oklch_to_lrgb.rb +5 -3
- data/lib/abachrome/converters/oklch_to_oklab.rb +5 -3
- data/lib/abachrome/converters/oklch_to_srgb.rb +6 -4
- data/lib/abachrome/converters/oklch_to_xyz.rb +6 -4
- data/lib/abachrome/converters/srgb_to_cmyk.rb +64 -0
- data/lib/abachrome/converters/srgb_to_lms.rb +29 -0
- data/lib/abachrome/converters/srgb_to_lrgb.rb +5 -3
- data/lib/abachrome/converters/srgb_to_oklab.rb +4 -2
- data/lib/abachrome/converters/srgb_to_oklch.rb +5 -3
- data/lib/abachrome/converters/srgb_to_xyz.rb +30 -0
- data/lib/abachrome/converters/srgb_to_yiq.rb +49 -0
- data/lib/abachrome/converters/xyz_to_lms.rb +5 -3
- data/lib/abachrome/converters/xyz_to_lrgb.rb +33 -0
- data/lib/abachrome/converters/xyz_to_oklab.rb +5 -3
- data/lib/abachrome/converters/xyz_to_srgb.rb +30 -0
- data/lib/abachrome/converters/yiq_to_srgb.rb +47 -0
- data/lib/abachrome/floatify.rb +282 -0
- data/lib/abachrome/gamut/base.rb +3 -3
- data/lib/abachrome/gamut/p3.rb +3 -3
- data/lib/abachrome/gamut/rec2020.rb +2 -2
- data/lib/abachrome/gamut/srgb.rb +4 -2
- data/lib/abachrome/illuminants/base.rb +2 -2
- data/lib/abachrome/illuminants/d50.rb +2 -2
- data/lib/abachrome/illuminants/d55.rb +2 -2
- data/lib/abachrome/illuminants/d65.rb +2 -2
- data/lib/abachrome/illuminants/d75.rb +2 -2
- data/lib/abachrome/named/css.rb +149 -149
- data/lib/abachrome/named/tailwind.rb +265 -265
- data/lib/abachrome/outputs/css.rb +2 -2
- data/lib/abachrome/palette.rb +26 -25
- data/lib/abachrome/palette_mixins/interpolate.rb +3 -1
- data/lib/abachrome/palette_mixins/resample.rb +2 -2
- data/lib/abachrome/palette_mixins/stretch_luminance.rb +2 -2
- data/lib/abachrome/parsers/css.rb +86 -71
- data/lib/abachrome/parsers/hex.rb +2 -2
- data/lib/abachrome/parsers/tailwind.rb +8 -8
- data/lib/abachrome/spectral.rb +277 -0
- data/lib/abachrome/to_abcd.rb +4 -4
- data/lib/abachrome/version.rb +2 -2
- data/lib/abachrome.rb +66 -10
- metadata +41 -3
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
# Abachrome::ColorSpace - Core color space definition and registry system
|
|
2
4
|
#
|
|
3
5
|
# This module provides the foundation for managing color spaces within the Abachrome library.
|
|
@@ -22,14 +24,14 @@ module Abachrome
|
|
|
22
24
|
class ColorSpace
|
|
23
25
|
class << self
|
|
24
26
|
# A registry of all registered color spaces.
|
|
25
|
-
#
|
|
27
|
+
#
|
|
26
28
|
# @return [Hash] A memoized hash where keys are color space identifiers and values are the corresponding color space objects
|
|
27
29
|
def registry
|
|
28
30
|
@registry ||= {}
|
|
29
31
|
end
|
|
30
32
|
|
|
31
33
|
# Registers a new color space with the specified name.
|
|
32
|
-
#
|
|
34
|
+
#
|
|
33
35
|
# @param name [String, Symbol] The identifier for the color space
|
|
34
36
|
# @param block [Proc] A block that configures the color space properties
|
|
35
37
|
# @return [Abachrome::ColorSpace] The newly created color space instance added to the registry
|
|
@@ -38,10 +40,10 @@ module Abachrome
|
|
|
38
40
|
end
|
|
39
41
|
|
|
40
42
|
# Aliases a color space name to an existing registered color space.
|
|
41
|
-
#
|
|
43
|
+
#
|
|
42
44
|
# This method creates an alias for an existing color space in the registry,
|
|
43
45
|
# allowing the same color space to be accessed through multiple names.
|
|
44
|
-
#
|
|
46
|
+
#
|
|
45
47
|
# @param name [Symbol, String] The existing color space name already registered
|
|
46
48
|
# @param aliased_name [Symbol, String] The new alias name to register
|
|
47
49
|
# @return [void]
|
|
@@ -60,7 +62,7 @@ module Abachrome
|
|
|
60
62
|
attr_reader :name, :coordinates, :white_point, :color_model
|
|
61
63
|
|
|
62
64
|
# Initialize a new ColorSpace instance.
|
|
63
|
-
#
|
|
65
|
+
#
|
|
64
66
|
# @param name [String, Symbol] The name of the color space, which will be converted to a symbol
|
|
65
67
|
# @return [Abachrome::ColorSpace] A new instance of ColorSpace
|
|
66
68
|
# @yield [self] Yields self to the block for configuration if a block is given
|
|
@@ -70,7 +72,7 @@ module Abachrome
|
|
|
70
72
|
end
|
|
71
73
|
|
|
72
74
|
# Sets the color coordinates for the current color space.
|
|
73
|
-
#
|
|
75
|
+
#
|
|
74
76
|
# @param [Array] coords The coordinate values that define a color in this color space.
|
|
75
77
|
# Multiple arguments or a single flat array can be provided.
|
|
76
78
|
# @return [Array] The flattened array of coordinates.
|
|
@@ -79,10 +81,10 @@ module Abachrome
|
|
|
79
81
|
end
|
|
80
82
|
|
|
81
83
|
# Sets the white point reference used by the color space.
|
|
82
|
-
#
|
|
84
|
+
#
|
|
83
85
|
# The white point is a reference that defines what is considered "white" in a color space.
|
|
84
86
|
# Common values include :D50, :D65, etc.
|
|
85
|
-
#
|
|
87
|
+
#
|
|
86
88
|
# @param point [Symbol, String] The white point reference to use (will be converted to Symbol)
|
|
87
89
|
# @return [Symbol] The newly set white point
|
|
88
90
|
def white_point=(point)
|
|
@@ -90,7 +92,7 @@ module Abachrome
|
|
|
90
92
|
end
|
|
91
93
|
|
|
92
94
|
# Sets the color model for the color space.
|
|
93
|
-
#
|
|
95
|
+
#
|
|
94
96
|
# @param model [String, Symbol] The new color model to set for this color space
|
|
95
97
|
# @return [Symbol] The color model as a symbolized value
|
|
96
98
|
def color_model=(model)
|
|
@@ -98,9 +100,9 @@ module Abachrome
|
|
|
98
100
|
end
|
|
99
101
|
|
|
100
102
|
# Compares this ColorSpace instance with another to check for equality.
|
|
101
|
-
#
|
|
103
|
+
#
|
|
102
104
|
# Two ColorSpace objects are considered equal if they have the same name.
|
|
103
|
-
#
|
|
105
|
+
#
|
|
104
106
|
# @param other [Object] The object to compare against
|
|
105
107
|
# @return [Boolean] true if other is a ColorSpace with the same name, false otherwise
|
|
106
108
|
def ==(other)
|
|
@@ -110,7 +112,7 @@ module Abachrome
|
|
|
110
112
|
end
|
|
111
113
|
|
|
112
114
|
# Checks if two color spaces are equal.
|
|
113
|
-
#
|
|
115
|
+
#
|
|
114
116
|
# @param other [Abachrome::ColorSpace] The color space to compare with
|
|
115
117
|
# @return [Boolean] true if the color spaces are equal, false otherwise
|
|
116
118
|
def eql?(other)
|
|
@@ -118,7 +120,7 @@ module Abachrome
|
|
|
118
120
|
end
|
|
119
121
|
|
|
120
122
|
# Returns a hash value for the color space based on its name.
|
|
121
|
-
#
|
|
123
|
+
#
|
|
122
124
|
# @return [Integer] A hash value computed from the color space name that can be
|
|
123
125
|
# used for equality comparison and as a hash key.
|
|
124
126
|
def hash
|
|
@@ -180,6 +182,18 @@ module Abachrome
|
|
|
180
182
|
s.white_point = :D65
|
|
181
183
|
s.color_model = :lms
|
|
182
184
|
end
|
|
185
|
+
|
|
186
|
+
ColorSpace.register(:yiq) do |s|
|
|
187
|
+
s.coordinates = %i[y i q]
|
|
188
|
+
s.white_point = :D65
|
|
189
|
+
s.color_model = :yiq
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
ColorSpace.register(:cmyk) do |s|
|
|
193
|
+
s.coordinates = %i[cyan magenta yellow key]
|
|
194
|
+
s.white_point = :D50
|
|
195
|
+
s.color_model = :cmyk
|
|
196
|
+
end
|
|
183
197
|
end
|
|
184
198
|
|
|
185
|
-
# Copyright (c) 2025 Durable Programming, LLC. All rights reserved.
|
|
199
|
+
# Copyright (c) 2025 Durable Programming, LLC. All rights reserved.
|
data/lib/abachrome/converter.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
# Abachrome::Converter - Color space conversion registry and orchestration system
|
|
2
4
|
#
|
|
3
5
|
# This module provides the central registry and conversion orchestration for transforming colors
|
|
@@ -22,18 +24,18 @@ module Abachrome
|
|
|
22
24
|
class Converter
|
|
23
25
|
class << self
|
|
24
26
|
# Returns the registry hash used to store color space converters.
|
|
25
|
-
#
|
|
27
|
+
#
|
|
26
28
|
# This method lazily initializes and returns the hash used internally to store
|
|
27
29
|
# converter mappings between different color spaces. This registry is a central
|
|
28
30
|
# repository that maps color space pairs to their appropriate conversion functions.
|
|
29
|
-
#
|
|
31
|
+
#
|
|
30
32
|
# @return [Hash] The converter registry hash, mapping color space pairs to converter functions
|
|
31
33
|
def registry
|
|
32
34
|
@registry ||= {}
|
|
33
35
|
end
|
|
34
36
|
|
|
35
37
|
# Register a converter class for transforming colors between two specific color spaces.
|
|
36
|
-
#
|
|
38
|
+
#
|
|
37
39
|
# @param from_space [Symbol, String] The source color space identifier
|
|
38
40
|
# @param to_space [Symbol, String] The destination color space identifier
|
|
39
41
|
# @param converter_class [Class] The converter class that implements the transformation
|
|
@@ -43,7 +45,7 @@ module Abachrome
|
|
|
43
45
|
end
|
|
44
46
|
|
|
45
47
|
# Converts a color from its current color space to the specified target color space.
|
|
46
|
-
#
|
|
48
|
+
#
|
|
47
49
|
# @param color [Abachrome::Color] The color to convert
|
|
48
50
|
# @param to_space_name [String, Symbol] The name of the target color space
|
|
49
51
|
# @return [Abachrome::Color] The color converted to the target color space
|
|
@@ -65,13 +67,13 @@ module Abachrome
|
|
|
65
67
|
# @example
|
|
66
68
|
# converter = Abachrome::Converter.new
|
|
67
69
|
# converter.register_all_converters
|
|
68
|
-
#
|
|
70
|
+
#
|
|
69
71
|
# Automatically registers all converter classes found in the Converters namespace.
|
|
70
72
|
# The method iterates through constants in the Converters module, identifies classes
|
|
71
73
|
# with naming pattern "FromSpaceToSpace" (e.g., LrgbToOklab), extracts the source
|
|
72
74
|
# and destination color spaces from the class name, and registers the converter
|
|
73
75
|
# class for the corresponding color space conversion.
|
|
74
|
-
#
|
|
76
|
+
#
|
|
75
77
|
# @return [void]
|
|
76
78
|
def register_all_converters
|
|
77
79
|
Converters.constants.each do |const_name|
|
|
@@ -92,7 +94,7 @@ module Abachrome
|
|
|
92
94
|
private
|
|
93
95
|
|
|
94
96
|
# Retrieves a converter function between two color spaces from the registry.
|
|
95
|
-
#
|
|
97
|
+
#
|
|
96
98
|
# @param from_space_name [String, Symbol] The source color space name
|
|
97
99
|
# @param to_space_name [String, Symbol] The target color space name
|
|
98
100
|
# @return [Proc, nil] The conversion function if registered, or nil if no converter exists for the specified color spaces
|
|
@@ -112,4 +114,4 @@ module Abachrome
|
|
|
112
114
|
Converter.register_all_converters
|
|
113
115
|
end
|
|
114
116
|
|
|
115
|
-
# Copyright (c) 2025 Durable Programming, LLC. All rights reserved.
|
|
117
|
+
# Copyright (c) 2025 Durable Programming, LLC. All rights reserved.
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
# Abachrome::Converters::Base - Abstract base class for color space converters
|
|
2
4
|
#
|
|
3
5
|
# This class provides the foundation for implementing color space conversion functionality
|
|
@@ -22,7 +24,7 @@ module Abachrome
|
|
|
22
24
|
attr_reader :from_space, :to_space
|
|
23
25
|
|
|
24
26
|
# Initialize a new converter between two color spaces.
|
|
25
|
-
#
|
|
27
|
+
#
|
|
26
28
|
# @param from_space [Abachrome::ColorSpace] The source color space to convert from
|
|
27
29
|
# @param to_space [Abachrome::ColorSpace] The target color space to convert to
|
|
28
30
|
# @return [Abachrome::Converters::Base] A new converter instance
|
|
@@ -32,7 +34,7 @@ module Abachrome
|
|
|
32
34
|
end
|
|
33
35
|
|
|
34
36
|
# Converts a color from one color space to another.
|
|
35
|
-
#
|
|
37
|
+
#
|
|
36
38
|
# @abstract This is an abstract method that must be implemented by subclasses.
|
|
37
39
|
# @param color [Abachrome::Color] The color to convert
|
|
38
40
|
# @return [Abachrome::Color] The converted color
|
|
@@ -42,7 +44,7 @@ module Abachrome
|
|
|
42
44
|
end
|
|
43
45
|
|
|
44
46
|
# Validates that a color uses the expected color model.
|
|
45
|
-
#
|
|
47
|
+
#
|
|
46
48
|
# @param color [Abachrome::Color] The color object to check
|
|
47
49
|
# @param model [Symbol, String] The expected color model
|
|
48
50
|
# @raise [RuntimeError] If the color's model doesn't match the expected model
|
|
@@ -54,10 +56,10 @@ module Abachrome
|
|
|
54
56
|
end
|
|
55
57
|
|
|
56
58
|
# Determines if the converter can handle the given color.
|
|
57
|
-
#
|
|
59
|
+
#
|
|
58
60
|
# This method checks if the color's current color space matches
|
|
59
61
|
# the converter's source color space.
|
|
60
|
-
#
|
|
62
|
+
#
|
|
61
63
|
# @param color [Abachrome::Color] The color to check
|
|
62
64
|
# @return [Boolean] true if the converter can convert from the color's current color space,
|
|
63
65
|
# false otherwise
|
|
@@ -66,7 +68,7 @@ module Abachrome
|
|
|
66
68
|
end
|
|
67
69
|
|
|
68
70
|
# Register a converter class for transforming colors between two specific color spaces.
|
|
69
|
-
#
|
|
71
|
+
#
|
|
70
72
|
# @param from_space_id [Symbol] The identifier of the source color space
|
|
71
73
|
# @param to_space_id [Symbol] The identifier of the destination color space
|
|
72
74
|
# @param converter_class [Class] The converter class that handles the transformation
|
|
@@ -77,7 +79,7 @@ module Abachrome
|
|
|
77
79
|
end
|
|
78
80
|
|
|
79
81
|
# Find a converter for converting between color spaces.
|
|
80
|
-
#
|
|
82
|
+
#
|
|
81
83
|
# @param from_space_id [Symbol, String] The identifier of the source color space
|
|
82
84
|
# @param to_space_id [Symbol, String] The identifier of the destination color space
|
|
83
85
|
# @return [Converter, nil] The converter instance for the specified color spaces, or nil if no converter is found
|
|
@@ -87,10 +89,10 @@ module Abachrome
|
|
|
87
89
|
end
|
|
88
90
|
|
|
89
91
|
# Converts a color from its current color space to a target color space.
|
|
90
|
-
#
|
|
92
|
+
#
|
|
91
93
|
# This method finds the appropriate converter class for the given source and
|
|
92
94
|
# target color spaces and performs the conversion.
|
|
93
|
-
#
|
|
95
|
+
#
|
|
94
96
|
# @param color [Abachrome::Color] The color to convert
|
|
95
97
|
# @param to_space [Abachrome::ColorSpace] The target color space to convert to
|
|
96
98
|
# @return [Abachrome::Color] The converted color in the target color space
|
|
@@ -110,7 +112,7 @@ module Abachrome
|
|
|
110
112
|
|
|
111
113
|
# Validates if a color can be converted from its current color space.
|
|
112
114
|
# Raises an ArgumentError if the color's space doesn't match the expected source space.
|
|
113
|
-
#
|
|
115
|
+
#
|
|
114
116
|
# @param color [Abachrome::Color] The color object to validate
|
|
115
117
|
# @raise [ArgumentError] If the color cannot be converted from its current color space
|
|
116
118
|
# @return [nil] Returns nil if the color is valid for conversion
|
|
@@ -123,4 +125,4 @@ module Abachrome
|
|
|
123
125
|
end
|
|
124
126
|
end
|
|
125
127
|
|
|
126
|
-
# Copyright (c) 2025 Durable Programming, LLC. All rights reserved.
|
|
128
|
+
# Copyright (c) 2025 Durable Programming, LLC. All rights reserved.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Abachrome::Converters::CmykToSrgb - CMYK to sRGB color space converter
|
|
4
|
+
#
|
|
5
|
+
# This converter transforms colors from the CMYK (Cyan, Magenta, Yellow, Key/Black)
|
|
6
|
+
# color space back to the standard RGB (sRGB) color space for display on screens.
|
|
7
|
+
#
|
|
8
|
+
# Key features:
|
|
9
|
+
# - Implements the standard CMYK to RGB conversion algorithm
|
|
10
|
+
# - Converts from subtractive (ink) to additive (light) color model
|
|
11
|
+
# - Maintains alpha channel transparency values during conversion
|
|
12
|
+
# - Uses BigDecimal arithmetic for precise color science calculations
|
|
13
|
+
# - Handles colors created with UCR/GCR correctly
|
|
14
|
+
#
|
|
15
|
+
# The conversion recombines the ink components (CMYK) back into light components (RGB)
|
|
16
|
+
# using the standard inverse transformation. Note that some CMYK colors may be
|
|
17
|
+
# out of gamut for sRGB displays.
|
|
18
|
+
|
|
19
|
+
module Abachrome
|
|
20
|
+
module Converters
|
|
21
|
+
class CmykToSrgb
|
|
22
|
+
# Converts a color from CMYK color space to sRGB color space.
|
|
23
|
+
# This method applies the standard CMYK to RGB transformation.
|
|
24
|
+
#
|
|
25
|
+
# @param cmyk_color [Abachrome::Color] A color object in the CMYK color space
|
|
26
|
+
# @return [Abachrome::Color] A new color object in the sRGB color space
|
|
27
|
+
# with the same alpha value as the input color
|
|
28
|
+
def self.convert(cmyk_color)
|
|
29
|
+
c, m, y, k = cmyk_color.coordinates.map { |component| AbcDecimal(component) }
|
|
30
|
+
|
|
31
|
+
# Use the CMYK color model's conversion method
|
|
32
|
+
r, g, b = ColorModels::CMYK.to_rgb(c, m, y, k)
|
|
33
|
+
|
|
34
|
+
Color.new(
|
|
35
|
+
ColorSpace.find(:srgb),
|
|
36
|
+
[r, g, b],
|
|
37
|
+
cmyk_color.alpha
|
|
38
|
+
)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -1,13 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Abachrome
|
|
2
4
|
module Converters
|
|
3
5
|
class LmsToLrgb < Abachrome::Converters::Base
|
|
4
6
|
# Converts a color from LMS color space to linear RGB color space.
|
|
5
|
-
#
|
|
7
|
+
#
|
|
6
8
|
# This method implements the final part of the OKLAB to linear RGB transformation,
|
|
7
9
|
# converting LMS (Long, Medium, Short) coordinates to linear RGB coordinates
|
|
8
10
|
# using the standard transformation matrix. The LMS color space represents
|
|
9
11
|
# the response of the three types of cone cells in the human eye.
|
|
10
|
-
#
|
|
12
|
+
#
|
|
11
13
|
# @param lms_color [Abachrome::Color] The color in LMS color space
|
|
12
14
|
# @raise [ArgumentError] If the input color is not in LMS color space
|
|
13
15
|
# @return [Abachrome::Color] The resulting color in linear RGB color space with
|
|
@@ -35,4 +37,4 @@ module Abachrome
|
|
|
35
37
|
end
|
|
36
38
|
end
|
|
37
39
|
|
|
38
|
-
# Copyright (c) 2025 Durable Programming, LLC. All rights reserved.
|
|
40
|
+
# Copyright (c) 2025 Durable Programming, LLC. All rights reserved.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Abachrome
|
|
4
|
+
module Converters
|
|
5
|
+
class LmsToOklab < Abachrome::Converters::Base
|
|
6
|
+
# Converts a color from LMS color space to OKLAB color space.
|
|
7
|
+
#
|
|
8
|
+
# This method converts LMS to LRGB first, then to OKLAB. The LMS color space
|
|
9
|
+
# represents the response of the three types of cone cells in the human eye.
|
|
10
|
+
#
|
|
11
|
+
# @param lms_color [Abachrome::Color] The color in LMS color space
|
|
12
|
+
# @raise [ArgumentError] If the input color is not in LMS color space
|
|
13
|
+
# @return [Abachrome::Color] The resulting color in OKLAB color space with
|
|
14
|
+
# the same alpha as the input color
|
|
15
|
+
def self.convert(lms_color)
|
|
16
|
+
raise_unless lms_color, :lms
|
|
17
|
+
|
|
18
|
+
# Convert LMS to LRGB first
|
|
19
|
+
lrgb_color = Converters::LmsToLrgb.convert(lms_color)
|
|
20
|
+
|
|
21
|
+
# Then convert LRGB to OKLAB
|
|
22
|
+
Converters::LrgbToOklab.convert(lrgb_color)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Copyright (c) 2025 Durable Programming, LLC. All rights reserved.
|
|
@@ -1,12 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Abachrome
|
|
2
4
|
module Converters
|
|
3
5
|
class LmsToSrgb < Abachrome::Converters::Base
|
|
4
6
|
# Converts a color from LMS color space to sRGB color space.
|
|
5
|
-
#
|
|
7
|
+
#
|
|
6
8
|
# This method implements a two-step conversion process:
|
|
7
9
|
# 1. First converts from LMS to linear RGB using the standard transformation matrix
|
|
8
10
|
# 2. Then converts from linear RGB to sRGB by applying gamma correction
|
|
9
|
-
#
|
|
11
|
+
#
|
|
10
12
|
# @param lms_color [Abachrome::Color] The color in LMS color space
|
|
11
13
|
# @raise [ArgumentError] If the input color is not in LMS color space
|
|
12
14
|
# @return [Abachrome::Color] The resulting color in sRGB color space with
|
|
@@ -14,7 +16,7 @@ module Abachrome
|
|
|
14
16
|
def self.convert(lms_color)
|
|
15
17
|
# First convert LMS to linear RGB
|
|
16
18
|
lrgb_color = LmsToLrgb.convert(lms_color)
|
|
17
|
-
|
|
19
|
+
|
|
18
20
|
# Then convert linear RGB to sRGB
|
|
19
21
|
LrgbToSrgb.convert(lrgb_color)
|
|
20
22
|
end
|
|
@@ -22,4 +24,4 @@ module Abachrome
|
|
|
22
24
|
end
|
|
23
25
|
end
|
|
24
26
|
|
|
25
|
-
# Copyright (c) 2025 Durable Programming, LLC. All rights reserved.
|
|
27
|
+
# Copyright (c) 2025 Durable Programming, LLC. All rights reserved.
|
|
@@ -1,14 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Abachrome
|
|
2
4
|
module Converters
|
|
3
5
|
class LmsToXyz < Abachrome::Converters::Base
|
|
4
6
|
# Converts a color from LMS color space to XYZ color space.
|
|
5
|
-
#
|
|
7
|
+
#
|
|
6
8
|
# This method implements the LMS to XYZ transformation using the standard
|
|
7
9
|
# transformation matrix. The LMS color space represents the response of
|
|
8
10
|
# the three types of cone cells in the human eye (Long, Medium, Short),
|
|
9
11
|
# while XYZ is the CIE 1931 color space that forms the basis for most
|
|
10
12
|
# other color space definitions.
|
|
11
|
-
#
|
|
13
|
+
#
|
|
12
14
|
# @param lms_color [Abachrome::Color] The color in LMS color space
|
|
13
15
|
# @raise [ArgumentError] If the input color is not in LMS color space
|
|
14
16
|
# @return [Abachrome::Color] The resulting color in XYZ color space with
|
|
@@ -29,4 +31,4 @@ module Abachrome
|
|
|
29
31
|
end
|
|
30
32
|
end
|
|
31
33
|
|
|
32
|
-
# Copyright (c) 2025 Durable Programming, LLC. All rights reserved.
|
|
34
|
+
# Copyright (c) 2025 Durable Programming, LLC. All rights reserved.
|
|
@@ -1 +1,29 @@
|
|
|
1
|
-
#
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Abachrome
|
|
4
|
+
module Converters
|
|
5
|
+
class LrgbToLms < Abachrome::Converters::Base
|
|
6
|
+
# Converts a color from linear RGB color space to LMS color space.
|
|
7
|
+
#
|
|
8
|
+
# This method converts linear RGB to XYZ first, then to LMS cone response space.
|
|
9
|
+
# The LMS color space represents the response of the three types of cone cells
|
|
10
|
+
# in the human eye (Long, Medium, Short wavelength sensitivity).
|
|
11
|
+
#
|
|
12
|
+
# @param lrgb_color [Abachrome::Color] The color in linear RGB color space
|
|
13
|
+
# @raise [ArgumentError] If the input color is not in linear RGB color space
|
|
14
|
+
# @return [Abachrome::Color] The resulting color in LMS color space with
|
|
15
|
+
# the same alpha as the input color
|
|
16
|
+
def self.convert(lrgb_color)
|
|
17
|
+
raise_unless lrgb_color, :lrgb
|
|
18
|
+
|
|
19
|
+
# Convert linear RGB to XYZ first
|
|
20
|
+
xyz_color = Converters::LrgbToXyz.convert(lrgb_color)
|
|
21
|
+
|
|
22
|
+
# Then convert XYZ to LMS
|
|
23
|
+
Converters::XyzToLms.convert(xyz_color)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Copyright (c) 2025 Durable Programming, LLC. All rights reserved.
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
# Abachrome::Converters::LrgbToOklab - Linear RGB to OKLAB color space converter
|
|
2
4
|
#
|
|
3
5
|
# This converter transforms colors from the linear RGB (LRGB) color space to the OKLAB color space
|
|
@@ -21,11 +23,11 @@ module Abachrome
|
|
|
21
23
|
module Converters
|
|
22
24
|
class LrgbToOklab < Abachrome::Converters::Base
|
|
23
25
|
# Converts a color from linear RGB (LRGB) color space to OKLAB color space.
|
|
24
|
-
#
|
|
26
|
+
#
|
|
25
27
|
# This conversion applies a matrix transformation to the linear RGB values,
|
|
26
28
|
# followed by a non-linear transformation, then another matrix transformation
|
|
27
29
|
# to produce OKLAB coordinates.
|
|
28
|
-
#
|
|
30
|
+
#
|
|
29
31
|
# @param rgb_color [Abachrome::Color] A color in linear RGB (LRGB) color space
|
|
30
32
|
# @raise [ArgumentError] If the provided color is not in LRGB color space
|
|
31
33
|
# @return [Abachrome::Color] The converted color in OKLAB color space with the same alpha value as the input
|
|
@@ -52,4 +54,4 @@ module Abachrome
|
|
|
52
54
|
end
|
|
53
55
|
end
|
|
54
56
|
|
|
55
|
-
# Copyright (c) 2025 Durable Programming, LLC. All rights reserved.
|
|
57
|
+
# Copyright (c) 2025 Durable Programming, LLC. All rights reserved.
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
# Abachrome::Converters::LrgbToSrgb - Linear RGB to sRGB color space converter
|
|
2
4
|
#
|
|
3
5
|
# This converter transforms colors from the linear RGB (LRGB) color space to the standard RGB (sRGB) color space by applying gamma correction. The conversion process applies the sRGB transfer function which uses different formulas for small and large values to match the non-linear response characteristics of typical display devices.
|
|
@@ -16,7 +18,7 @@ module Abachrome
|
|
|
16
18
|
module Converters
|
|
17
19
|
class LrgbToSrgb < Abachrome::Converters::Base
|
|
18
20
|
# Converts a color from linear RGB to sRGB color space.
|
|
19
|
-
#
|
|
21
|
+
#
|
|
20
22
|
# @param lrgb_color [Abachrome::Color] The color in linear RGB color space to convert
|
|
21
23
|
# @return [Abachrome::Color] A new Color object in sRGB color space with the converted coordinates
|
|
22
24
|
# @raise [TypeError] If the provided color is not in linear RGB color space
|
|
@@ -34,11 +36,11 @@ module Abachrome
|
|
|
34
36
|
end
|
|
35
37
|
|
|
36
38
|
# Converts a linear RGB value to standard RGB color space (sRGB) value.
|
|
37
|
-
#
|
|
39
|
+
#
|
|
38
40
|
# This method implements the standard linearization function used in the sRGB color space.
|
|
39
41
|
# For small values (≤ 0.0031308), a simple linear transformation is applied.
|
|
40
42
|
# For larger values, a power function with gamma correction is used.
|
|
41
|
-
#
|
|
43
|
+
#
|
|
42
44
|
# @param v [AbcDecimal] The linear RGB value to convert
|
|
43
45
|
# @return [AbcDecimal] The corresponding sRGB value, preserving the sign of the input
|
|
44
46
|
def self.to_srgb(v)
|
|
@@ -54,4 +56,4 @@ module Abachrome
|
|
|
54
56
|
end
|
|
55
57
|
end
|
|
56
58
|
|
|
57
|
-
# Copyright (c) 2025 Durable Programming, LLC. All rights reserved.
|
|
59
|
+
# Copyright (c) 2025 Durable Programming, LLC. All rights reserved.
|
|
@@ -1,13 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Abachrome
|
|
2
4
|
module Converters
|
|
3
5
|
class LrgbToXyz < Abachrome::Converters::Base
|
|
4
6
|
# Converts a color from linear RGB color space to XYZ color space.
|
|
5
|
-
#
|
|
7
|
+
#
|
|
6
8
|
# This method implements the linear RGB to XYZ transformation using the standard
|
|
7
9
|
# transformation matrix for the sRGB color space with D65 white point. The XYZ
|
|
8
10
|
# color space is the CIE 1931 color space that forms the basis for most other
|
|
9
11
|
# color space definitions and serves as a device-independent reference.
|
|
10
|
-
#
|
|
12
|
+
#
|
|
11
13
|
# @param lrgb_color [Abachrome::Color] The color in linear RGB color space
|
|
12
14
|
# @raise [ArgumentError] If the input color is not in linear RGB color space
|
|
13
15
|
# @return [Abachrome::Color] The resulting color in XYZ color space with
|
|
@@ -28,4 +30,4 @@ module Abachrome
|
|
|
28
30
|
end
|
|
29
31
|
end
|
|
30
32
|
|
|
31
|
-
# Copyright (c) 2025 Durable Programming, LLC. All rights reserved.
|
|
33
|
+
# Copyright (c) 2025 Durable Programming, LLC. All rights reserved.
|
|
@@ -1,12 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Abachrome
|
|
2
4
|
module Converters
|
|
3
5
|
class OklabToLms < Abachrome::Converters::Base
|
|
4
6
|
# Converts a color from OKLAB color space to LMS color space.
|
|
5
|
-
#
|
|
7
|
+
#
|
|
6
8
|
# This method implements the first part of the OKLAB to linear RGB transformation,
|
|
7
9
|
# converting OKLAB coordinates to the intermediate LMS (Long, Medium, Short) color space
|
|
8
10
|
# which represents the response of the three types of cone cells in the human eye.
|
|
9
|
-
#
|
|
11
|
+
#
|
|
10
12
|
# @param oklab_color [Abachrome::Color] The color in OKLAB color space
|
|
11
13
|
# @raise [ArgumentError] If the input color is not in OKLAB color space
|
|
12
14
|
# @return [Abachrome::Color] The resulting color in LMS color space with
|
|
@@ -16,15 +18,15 @@ module Abachrome
|
|
|
16
18
|
|
|
17
19
|
l, a, b = oklab_color.coordinates.map { |_| AbcDecimal(_) }
|
|
18
20
|
|
|
19
|
-
l_ = AbcDecimal(
|
|
21
|
+
l_ = AbcDecimal(l +
|
|
20
22
|
(AD("0.39633779217376785678") * a) +
|
|
21
23
|
(AD("0.21580375806075880339") * b))
|
|
22
24
|
|
|
23
|
-
m_ = AbcDecimal(
|
|
25
|
+
m_ = AbcDecimal(l -
|
|
24
26
|
(a * AD("-0.1055613423236563494")) +
|
|
25
27
|
(b * AD("-0.063854174771705903402")))
|
|
26
|
-
|
|
27
|
-
s_ = AbcDecimal(
|
|
28
|
+
|
|
29
|
+
s_ = AbcDecimal(l -
|
|
28
30
|
(a * AD("-0.089484182094965759684")) +
|
|
29
31
|
(b * AD("-1.2914855378640917399")))
|
|
30
32
|
|
|
@@ -39,4 +41,4 @@ module Abachrome
|
|
|
39
41
|
end
|
|
40
42
|
end
|
|
41
43
|
|
|
42
|
-
# Copyright (c) 2025 Durable Programming, LLC. All rights reserved.
|
|
44
|
+
# Copyright (c) 2025 Durable Programming, LLC. All rights reserved.
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
# Abachrome::Converters::OklabToLrgb - OKLAB to Linear RGB color space converter
|
|
2
4
|
#
|
|
3
5
|
# This converter transforms colors from the OKLAB color space to the linear RGB (LRGB) color space
|
|
@@ -39,9 +41,8 @@ module Abachrome
|
|
|
39
41
|
# Step 1: OKLAB to L'M'S' (cone responses, non-linear)
|
|
40
42
|
# These are the M_lms_prime_from_oklab matrix operations.
|
|
41
43
|
l_prime = AbcDecimal(l_ok + (AD("0.39633779217376785678") * a_ok) + (AD("0.21580375806075880339") * b_ok))
|
|
42
|
-
m_prime = AbcDecimal(l_ok - (a_ok * AD("0.1055613423236563494")) - (b_ok * AD("0.063854174771705903402"))) #
|
|
43
|
-
s_prime = AbcDecimal(l_ok - (a_ok * AD("0.089484182094965759684")) - (b_ok * AD("1.2914855378640917399"))) #
|
|
44
|
-
|
|
44
|
+
m_prime = AbcDecimal(l_ok - (a_ok * AD("0.1055613423236563494")) - (b_ok * AD("0.063854174771705903402"))) # NOTE: original OklabToLms had + (b * AD("-0.063..."))
|
|
45
|
+
s_prime = AbcDecimal(l_ok - (a_ok * AD("0.089484182094965759684")) - (b_ok * AD("1.2914855378640917399"))) # NOTE: original OklabToLms had + (b * AD("-1.291..."))
|
|
45
46
|
|
|
46
47
|
# Step 2: L'M'S' to LMS (cubing)
|
|
47
48
|
l_lms = l_prime**3
|
|
@@ -50,9 +51,9 @@ module Abachrome
|
|
|
50
51
|
|
|
51
52
|
# Step 3: LMS to LRGB
|
|
52
53
|
# Using matrix M_lrgb_from_lms (OKLAB specific)
|
|
53
|
-
r_lrgb = (l_lms * AD("4.07674166134799"))
|
|
54
|
+
r_lrgb = (l_lms * AD("4.07674166134799")) + (m_lms * AD("-3.307711590408193")) + (s_lms * AD("0.230969928729428"))
|
|
54
55
|
g_lrgb = (l_lms * AD("-1.2684380040921763")) + (m_lms * AD("2.6097574006633715")) + (s_lms * AD("-0.3413193963102197"))
|
|
55
|
-
b_lrgb = (l_lms * AD("-0.004196086541837188"))+ (m_lms * AD("-0.7034186144594493")) + (s_lms * AD("1.7076147009309444"))
|
|
56
|
+
b_lrgb = (l_lms * AD("-0.004196086541837188")) + (m_lms * AD("-0.7034186144594493")) + (s_lms * AD("1.7076147009309444"))
|
|
56
57
|
|
|
57
58
|
# Clamp LRGB values to be non-negative (as done in LmsToLrgb.rb)
|
|
58
59
|
# It's also common to clamp to [0, 1] range after conversion from a wider gamut space
|
|
@@ -61,11 +62,10 @@ module Abachrome
|
|
|
61
62
|
# Here, we'll ensure non-negative as per LmsToLrgb.
|
|
62
63
|
output_coords = [r_lrgb, g_lrgb, b_lrgb].map { |it| [it, AD(0)].max }
|
|
63
64
|
|
|
64
|
-
|
|
65
65
|
Color.new(ColorSpace.find(:lrgb), output_coords, oklab_color.alpha)
|
|
66
66
|
end
|
|
67
67
|
end
|
|
68
68
|
end
|
|
69
69
|
end
|
|
70
70
|
|
|
71
|
-
# Copyright (c) 2025 Durable Programming, LLC. All rights reserved.
|
|
71
|
+
# Copyright (c) 2025 Durable Programming, LLC. All rights reserved.
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
# Abachrome::Converters::OklabToOklch - OKLAB to OKLCH color space converter
|
|
2
4
|
#
|
|
3
5
|
# This converter transforms colors from the OKLAB color space to the OKLCH color space
|
|
@@ -28,7 +30,7 @@ module Abachrome
|
|
|
28
30
|
# - L (lightness) remains the same
|
|
29
31
|
# - C (chroma) is calculated as the Euclidean distance from the origin in the a-b plane
|
|
30
32
|
# - h (hue) is calculated as the angle in the a-b plane
|
|
31
|
-
#
|
|
33
|
+
#
|
|
32
34
|
# @param oklab_color [Abachrome::Color] A color in the OKLAB color space
|
|
33
35
|
# @raise [ArgumentError] If the provided color is not in OKLAB color space
|
|
34
36
|
# @return [Abachrome::Color] The equivalent color in OKLCH color space with the same alpha value
|
|
@@ -51,4 +53,4 @@ module Abachrome
|
|
|
51
53
|
end
|
|
52
54
|
end
|
|
53
55
|
|
|
54
|
-
# Copyright (c) 2025 Durable Programming, LLC. All rights reserved.
|
|
56
|
+
# Copyright (c) 2025 Durable Programming, LLC. All rights reserved.
|