module Decolmor::ClassMethods

Attributes

hsx_round[W]

Public Instance Methods

cmyk_to_hex(cmyk_arr, alpha_255: false) click to toggle source
# File lib/decolmor/main.rb, line 339
def cmyk_to_hex(cmyk_arr, alpha_255: false)
  rgb = cmyk_to_rgb(cmyk_arr)
  rgb_to_hex(rgb, alpha_255: alpha_255)
end
cmyk_to_rgb(cmyk_arr) click to toggle source
# File lib/decolmor/main.rb, line 288
def cmyk_to_rgb(cmyk_arr)
  c, m, y, k = cmyk_arr[0..3].map { |color| color / 100.to_f }
  converter = proc do |channel|
    255 * (1 - channel) * (1 - k)
  end

  # calculation RGB & rounding
  rgb = [c, m, y].map { |channel| converter.call(channel).round }
  cmyk_arr.size == 5 ? rgb + [cmyk_arr.last] : rgb
end
hex_to_cmyk(hex, rounding = hsx_round, alpha_255: false) click to toggle source
# File lib/decolmor/main.rb, line 334
def hex_to_cmyk(hex, rounding = hsx_round, alpha_255: false)
  rgb = hex_to_rgb(hex, alpha_255: alpha_255)
  rgb_to_cmyk(rgb, rounding)
end
hex_to_hsb(hex, rounding = hsx_round, alpha_255: false)
Alias for: hex_to_hsv
hex_to_hsi(hex, rounding = hsx_round, alpha_255: false) click to toggle source
# File lib/decolmor/main.rb, line 324
def hex_to_hsi(hex, rounding = hsx_round, alpha_255: false)
  rgb = hex_to_rgb(hex, alpha_255: alpha_255)
  rgb_to_hsi(rgb, rounding)
end
hex_to_hsl(hex, rounding = hsx_round, alpha_255: false) click to toggle source
HEX <==> HSL/HSV/HSB/HSI ========================================
# File lib/decolmor/main.rb, line 301
def hex_to_hsl(hex, rounding = hsx_round, alpha_255: false)
  rgb = hex_to_rgb(hex, alpha_255: alpha_255)
  rgb_to_hsl(rgb, rounding)
end
hex_to_hsv(hex, rounding = hsx_round, alpha_255: false) click to toggle source
# File lib/decolmor/main.rb, line 311
def hex_to_hsv(hex, rounding = hsx_round, alpha_255: false)
  rgb = hex_to_rgb(hex, alpha_255: alpha_255)
  rgb_to_hsv(rgb, rounding)
end
Also aliased as: hex_to_hsb
hex_to_rgb(hex, alpha_round = 3, alpha_255: false) click to toggle source
HEX <==> RGB(A) =============================================
# File lib/decolmor/main.rb, line 24
def hex_to_rgb(hex, alpha_round = 3, alpha_255: false)
  hex = hex.gsub('#','')
  hex = if [3, 4].include? hex.length
          hex.chars.map{ |char| char * 2 }
        else
          hex.scan(/../)
        end
  rgb = hex.map(&:hex)
  if rgb.size == 4
    rgb[3] = (rgb[3] / 255.to_f).round(alpha_round) unless alpha_255
  end

  rgb
end
hsb_to_hex(hsv_arr, alpha_255: false)
Alias for: hsv_to_hex
hsb_to_hsl(hsv_arr, rounding = hsx_round)
Alias for: hsv_to_hsl
hsb_to_rgb(hsv_arr)
Alias for: hsv_to_rgb
hsb_to_rgb_alt(hsv_arr)
Alias for: hsv_to_rgb_alt
hsi_to_hex(hsi_arr, alpha_255: false) click to toggle source
# File lib/decolmor/main.rb, line 329
def hsi_to_hex(hsi_arr, alpha_255: false)
  rgb = hsi_to_rgb(hsi_arr)
  rgb_to_hex(rgb, alpha_255: alpha_255)
end
hsi_to_rgb(hsi_arr) click to toggle source
# File lib/decolmor/main.rb, line 203
def hsi_to_rgb(hsi_arr)
  hue, saturation, intensity, alpha = hsi_arr.map(&:to_f)
  # scaling values into range 0..1
  saturation /= 100
  intensity /= 100

  # calculation chroma & intermediate values
  #
  # as 360/60 does not get_rgb_point in any of the ranges 0...1 or 5...6
  # so in the method we use (hue % 360)
  # at the same time solving if hue is not in the 0..360 range
  hue = (hue % 360) / 60
  z = 1 - (hue % 2 - 1).abs
  chroma = (3 * intensity * saturation) / (1 + z)
  x = chroma * z
  point = get_rgb_point(hue, chroma, x)

  # calculation rgb
  m = intensity * (1 - saturation)
  rgb = point.map { |channel|  channel + m }

  # checking rgb on overrange 0..1
  rgb = fix_overrange_rgb(rgb)
  # scaling into range 0..255 & rounding
  rgb.map! { |channel|  (channel * 255).round }

  alpha.nil? ? rgb : rgb + [alpha]
end
hsl_to_hex(hsl_arr, alpha_255: false) click to toggle source
# File lib/decolmor/main.rb, line 306
def hsl_to_hex(hsl_arr, alpha_255: false)
  rgb = hsl_to_rgb(hsl_arr)
  rgb_to_hex(rgb, alpha_255: alpha_255)
end
hsl_to_hsb(hsl_arr, rounding = hsx_round)
Alias for: hsl_to_hsv
hsl_to_hsv(hsl_arr, rounding = hsx_round) click to toggle source
HSL <==> HSV (HSB) ==========================================
# File lib/decolmor/main.rb, line 234
def hsl_to_hsv(hsl_arr, rounding = hsx_round)
  hue, saturation, lightness, alpha = hsl_arr.map(&:to_f)
  # scaling values into range 0..1
  saturation /= 100
  lightness /= 100

  # calculation value & saturation HSV
  value = lightness + saturation * [lightness, 1 - lightness].min
  saturation_hsv = lightness == 0 ? 0 : 2 * (1 - lightness / value)

  # scaling HSV values & rounding
  hsv = [hue, saturation_hsv * 100, value * 100].map { |x| x.round(rounding) }
  alpha.nil? ? hsv : hsv + [alpha]
end
Also aliased as: hsl_to_hsb
hsl_to_rgb(hsl_arr) click to toggle source
HSL/HSV/HSB to RGB(A) =======================================
# File lib/decolmor/main.rb, line 105
def hsl_to_rgb(hsl_arr)
  hue, saturation, lightness, alpha = hsl_arr.map(&:to_f)
  # scaling values into range 0..1
  saturation /= 100
  lightness /= 100

  # calculation intermediate values
  a = saturation * [lightness, 1 - lightness].min

  # calculation rgb & scaling into range 0..255
  rgb = [0, 8, 4]
  rgb.map! do |channel|
    k = (channel + hue / 30) % 12
    channel = lightness - a * [-1, [k - 3, 9 - k, 1].min].max
    (channel * 255).round
  end
  alpha.nil? ? rgb : rgb + [alpha]
end
hsl_to_rgb_alt(hsl_arr) click to toggle source
Alternative implementation HSL/HSV/HSB to RGB(A) ============
# File lib/decolmor/main.rb, line 144
def hsl_to_rgb_alt(hsl_arr)
  hue, saturation, lightness, alpha = hsl_arr.map(&:to_f)
  # scaling values into range 0..1
  saturation /= 100
  lightness /= 100

  # calculation chroma & intermediate values
  hue = (hue % 360) / 60
  chroma = (1 - (2 * lightness - 1).abs) * saturation
  x = chroma * (1 - (hue % 2 - 1).abs)
  point = get_rgb_point(hue, chroma, x)

  # calculation rgb & scaling into range 0..255
  m = lightness - chroma / 2
  rgb = point.map { |channel| ((channel + m) * 255).round }
  alpha.nil? ? rgb : rgb + [alpha]
end
hsv_to_hex(hsv_arr, alpha_255: false) click to toggle source
# File lib/decolmor/main.rb, line 316
def hsv_to_hex(hsv_arr, alpha_255: false)
  rgb = hsv_to_rgb(hsv_arr)
  rgb_to_hex(rgb, alpha_255: alpha_255)
end
Also aliased as: hsb_to_hex
hsv_to_hsl(hsv_arr, rounding = hsx_round) click to toggle source
# File lib/decolmor/main.rb, line 251
def hsv_to_hsl(hsv_arr, rounding = hsx_round)
  hue, saturation, value, alpha = hsv_arr.map(&:to_f)
  # scaling values into range 0..1
  saturation /= 100
  value /= 100

  # calculation lightness & saturation HSL
  lightness = value * (1 - saturation / 2)
  saturation_hsl = if [0, 1].any? { |v| v == lightness }
                     0
                   else
                     (value - lightness) / [lightness, 1 - lightness].min
                   end

  # scaling HSL values & rounding
  hsl = [hue, saturation_hsl * 100, lightness * 100].map { |x| x.round(rounding) }
  alpha.nil? ? hsl : hsl + [alpha]
end
Also aliased as: hsb_to_hsl
hsv_to_rgb(hsv_arr) click to toggle source
# File lib/decolmor/main.rb, line 124
def hsv_to_rgb(hsv_arr)
  hue, saturation, value, alpha = hsv_arr.map(&:to_f)
  # scaling values into range 0..1
  saturation /= 100
  value /= 100

  # calculation rgb & scaling into range 0..255
  rgb = [5, 3, 1]
  rgb.map! do |channel|
    k = (channel + hue / 60) % 6
    channel = value - value * saturation * [0, [k, 4 - k, 1].min].max
    (channel * 255).round
  end
  alpha.nil? ? rgb : rgb + [alpha]
end
Also aliased as: hsb_to_rgb
hsv_to_rgb_alt(hsv_arr) click to toggle source
# File lib/decolmor/main.rb, line 162
def hsv_to_rgb_alt(hsv_arr)
  hue, saturation, value, alpha = hsv_arr.map(&:to_f)
  # scaling values into range 0..1
  saturation /= 100
  value /= 100

  # calculation chroma & intermediate values
  hue = (hue % 360) / 60
  chroma = value * saturation
  x = chroma * (1 - (hue % 2 - 1).abs)
  point = get_rgb_point(hue, chroma, x)

  # calculation rgb & scaling into range 0..255
  m = value - chroma
  rgb = point.map { |channel| ((channel + m) * 255).round }
  alpha.nil? ? rgb : rgb + [alpha]
end
Also aliased as: hsb_to_rgb_alt
hsx_round() click to toggle source
# File lib/decolmor/main.rb, line 18
def hsx_round
  @hsx_round ||= HSX_ROUND
end
new_rgb(red: nil, green: nil, blue: nil, alpha: nil) click to toggle source

simple generator RGB, you can set any channel(s)

# File lib/decolmor/main.rb, line 51
def new_rgb(red: nil, green: nil, blue: nil, alpha: nil)
  range = 0..255
  rgb = [red, green, blue].map { |channel| channel || rand(range) }
  alpha.nil? ? rgb : rgb + [alpha]
end
rgb_to_cmyk(rgb_arr, rounding = hsx_round) click to toggle source
RGB(A) <==> CMYK ============================================
# File lib/decolmor/main.rb, line 274
def rgb_to_cmyk(rgb_arr, rounding = hsx_round)
  # scaling RGB values into range 0..1
  rgb = rgb_arr[0..2].map { |color| color / 255.to_f }
  k = 1 - rgb.max
  converter = proc do |color|
     (1 - k) == 0 ? 0 : (1 - color - k) / (1 - k)
  end

  # calculation CMYK & scaling into percentages & rounding
  c, m, y = rgb.map { |color| converter.call(color) || 0 }
  cmyk = [c, m, y, k].map { |x| (x * 100).round(rounding) }
  rgb_arr.size == 4 ? cmyk + [rgb_arr.last] : cmyk
end
rgb_to_hex(rgb, alpha_255: false) click to toggle source
# File lib/decolmor/main.rb, line 39
def rgb_to_hex(rgb, alpha_255: false)
  if rgb.size == 3
    "#%02X%02X%02X" % rgb
  else
    rgb[3] = (rgb[3] * 255).round unless alpha_255
    "#%02X%02X%02X%02X" % rgb
  end
end
rgb_to_hsb(rgb_arr, rounding = hsx_round)
Alias for: rgb_to_hsv
rgb_to_hsi(rgb_arr, rounding = hsx_round) click to toggle source
RGB <==> HSI ================================================
# File lib/decolmor/main.rb, line 184
def rgb_to_hsi(rgb_arr, rounding = hsx_round)
  # scaling RGB values into range 0..1
  rgb = rgb_arr[0..2].map { |color| color / 255.to_f }
  alpha = rgb_arr[3]

  # calculation HSI values
  hue = get_hue(*rgb)
  intensity = rgb.sum / 3
  saturation = intensity.zero? ? 0 : 1 - rgb.min / intensity

  # scaling values to fill 0..100 interval
  saturation *= 100
  intensity *= 100

  # rounding, drop Alpha if not set (nil)
  hsi = [hue, saturation, intensity].map { |x| x.round(rounding) }
  alpha.nil? ? hsi : hsi + [alpha]
end
rgb_to_hsl(rgb_arr, rounding = hsx_round) click to toggle source
RGB(A) to HSL/HSV/HSB =======================================
# File lib/decolmor/main.rb, line 59
def rgb_to_hsl(rgb_arr, rounding = hsx_round)
  # scaling RGB values into range 0..1
  red, green, blue, alpha = rgb_arr.map { |color| color / 255.to_f }

  # calculation intermediate values
  cmin, cmax, chroma = get_min_max_chroma(red, green, blue)

  # calculation HSL values
  hue = get_hue(red, green, blue)
  lightness = (cmax + cmin) / 2
  saturation = chroma == 0 ? 0 : chroma / (1 - (2 * lightness - 1).abs)

  # scaling values to fill 0..100 interval
  saturation *= 100
  lightness *= 100

  # rounding, drop Alpha if not set (nil)
  hsl = [hue, saturation, lightness].map { |x| x.round(rounding) }
  alpha.nil? ? hsl : hsl + [alpha * 255]
end
rgb_to_hsv(rgb_arr, rounding = hsx_round) click to toggle source
# File lib/decolmor/main.rb, line 80
def rgb_to_hsv(rgb_arr, rounding = hsx_round)
  # scaling RGB values into range 0..1
  red, green, blue, alpha = rgb_arr.map { |color| color / 255.to_f }

  # calculation intermediate values
  _cmin, cmax, chroma = get_min_max_chroma(red, green, blue)

  # calculation HSV values
  hue = get_hue(red, green, blue)
  saturation = chroma == 0 ? 0 : chroma / cmax
  value = cmax

  # scaling values into range 0..100
  saturation *= 100
  value *= 100

  # rounding
  hsv = [hue, saturation, value].map { |x| x.round(rounding) }
  alpha.nil? ? hsv : hsv + [alpha * 255]
end
Also aliased as: rgb_to_hsb

Private Instance Methods

fix_overrange_rgb(rgb) click to toggle source

checking rgb on overrange 0..1

# File lib/decolmor/main.rb, line 398
def fix_overrange_rgb(rgb)
  max = rgb.max
  # so we keep HUE
  # if we had just used clipping [[value, 255].min, 0].max
  # we would have changed HUE
  #
  # Thx to Rotem & Giacomo Catenazzi from stackoverflow
  max > 1 ? rgb.map { |channel|  channel / max } : rgb
end
get_hue(red, green, blue) click to toggle source

calculation HUE from RGB

# File lib/decolmor/main.rb, line 360
def get_hue(red, green, blue)
  _cmin, cmax, chroma = get_min_max_chroma(red, green, blue)

  hue = if chroma == 0
          0
        elsif cmax == red
          # red is max
          ((green - blue) / chroma) % 6
        elsif cmax == green
          # green is max
          (blue - red) / chroma + 2
        else
          # blue is max
          (red - green) / chroma + 4
        end
  hue * 60

  # HUE will never leave the 0..360 range when RGB is within 0..255
  # make negative HUEs positive
  # 0 <= hue ? hue : hue + 360
end
get_min_max_chroma(red, green, blue) click to toggle source

find greatest and smallest channel values and chroma from RGB

# File lib/decolmor/main.rb, line 350
def get_min_max_chroma(red, green, blue)
  cmin = [red, green, blue].min
  cmax = [red, green, blue].max
  # calculation chroma
  chroma = cmax - cmin

  [cmin, cmax, chroma]
end
get_rgb_point(hue, chroma, x) click to toggle source

possible RGB points point selection based on entering HUE input in range

# File lib/decolmor/main.rb, line 384
def get_rgb_point(hue, chroma, x)
  case hue
  when 0...1 then [chroma, x, 0]
  when 1...2 then [x, chroma, 0]
  when 2...3 then [0, chroma, x]
  when 3...4 then [0, x, chroma]
  when 4...5 then [x, 0, chroma]
  when 5...6 then [chroma, 0, x]
  # HUE will never leave the 0..359 range because we use (hue % 360)
  # else [0, 0, 0]
  end
end