Module: Colir::HSLRGB
- Defined in:
- lib/colir/hslrgb.rb
Overview
The module provides methods for RGB to HSL and HSL to RGB conversions. I just ported it from a C implementation.
Defined Under Namespace
Constant Summary collapse
- RGB_ORDER_CODES =
The cached array of arrays, which contains order codes for the model from ‘::hsl_to_rgb`. The model is an array, where the needed for conversion values are calculated only once. The order codes allows to refer to the calculated model array values via indices. Hopefully, it saves some CPU cycles.
[ [0, 1, 2], # [0, 60) [1, 0, 2], # [60, 120) [2, 0, 1], # [120, 180) [2, 1, 0], # [180, 240) [1, 2, 0], # [240, 300) [0, 2, 1], # [300, 360) ]
- RGB_DEFAULT_CODE =
The code returned for 0 or 360 degrees.
[2, 2, 2]
Class Method Summary collapse
-
.hsl_to_rgb(hue, saturation, lightness) ⇒ Array<Integer>
Converts an HSL colour to its RGB counterpart.
-
.rgb_to_hsl(red, green, blue) ⇒ Array<Integer,BigDecimal>
Converts an RGB colour to its HSL counterpart.
Class Method Details
.hsl_to_rgb(hue, saturation, lightness) ⇒ Array<Integer>
Converts an HSL colour to its RGB counterpart. The algorithm is correct, but sometimes you’ll notice little laxity (because of rounding problems).
170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 |
# File 'lib/colir/hslrgb.rb', line 170 def self.hsl_to_rgb(hue, saturation, lightness) validate_hsl!([hue, saturation, lightness]) chroma = (1 - (2 * lightness - 1).abs) * saturation a = 1 * (lightness - 0.5 * chroma) b = chroma * (1 - ((hue / BigDecimal('60.0')).modulo(2) - 1).abs) degrees = Array.new(7) { |idx| idx * 60 }.each model = [chroma+a, a+b, a] RGB_ORDER_CODES.find(->{RGB_DEFAULT_CODE}) { (degrees.next...degrees.peek) === hue }.map { |id| (model[id] * 255).round } end |
.rgb_to_hsl(red, green, blue) ⇒ Array<Integer,BigDecimal>
Converts an RGB colour to its HSL counterpart.
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/colir/hslrgb.rb', line 118 def self.rgb_to_hsl(red, green, blue) validate_rgb!([red, green, blue]) red, green, blue = [red, green, blue].map { |b| b / BigDecimal('255.0') } min, max = [red, green, blue].minmax chroma = max - min lightness = (min + max) * BigDecimal('0.5') hue = 0 saturation = BigDecimal('0.0') if chroma.nonzero? hue = case max when red then (green - blue) / chroma % 6 when green then (blue - red) / chroma + 2 else (red - green) / chroma + 4 end hue = (hue * 60).round saturation = chroma / (1 - (2 * lightness - 1).abs) end [hue, saturation, lightness] end |