local max_value = 15 -- helper function function toHex(decimal) if (decimal < 0) then decimal = 0 end if (decimal > max_value) then decimal = max_value end local hex = string.format("%01x", decimal) return hex end -- magic hsv/rgb functions function hue_to_rgb(p, q, t) if t < 0 then t = t + 1 end if t > 1 then t = t - 1 end if t < 1/6 then return p + (q - p) * 6 * t end if t < 1/2 then return q end if t < 2/3 then return p + (q - p) * (2/3 - t) * 6 end return p end -- magic hsv/rgb functions function hsl_to_rgb(h, s, l) local r, g, b if s == 0 then r = l g = l b = l else local q = l < 0.5 and l * (1 + s) or l + s - l * s local p = 2 * l - q r = hue_to_rgb(p, q, h + 1/3) g = hue_to_rgb(p, q, h) b = hue_to_rgb(p, q, h - 1/3) end return math.floor(r * max_value), math.floor(g * max_value), math.floor(b * max_value) end -- magic hsv/rgb functions function hsv_to_rgb(h, s, v) local r, g, b local i = math.floor(h * 6) local f = h * 6 - i local p = v * (1 - s) local q = v * (1 - f * s) local t = v * (1 - (1 - f) * s) i = i % 6 if i == 0 then r, g, b = v, t, p elseif i == 1 then r, g, b = q, v, p elseif i == 2 then r, g, b = p, v, t elseif i == 3 then r, g, b = p, q, v elseif i == 4 then r, g, b = t, p, v elseif i == 5 then r, g, b = v, p, q end return math.floor(r * max_value), math.floor(g * max_value), math.floor(b * max_value) end -- magic oklab stuff function lch_to_lab(L, C, h) local a = C * math.cos(h * math.pi / 180) local b = C * math.sin(h * math.pi / 180) return L, a, b end -- magic oklab stuff function oklab_to_linear_srgb(L, a, b) local l_ = (L + 0.3963377774 * a + 0.2158037573 * b) ^ 3 local m_ = (L - 0.1055613458 * a - 0.0638541728 * b) ^ 3 local s_ = (L - 0.0894841775 * a - 1.2914855480 * b) ^ 3 local r = 4.0767416621 * l_ - 3.3077115913 * m_ + 0.2309699292 * s_ local g = -1.2684380046 * l_ + 2.6097574011 * m_ - 0.3413193965 * s_ local b = -0.0041960863 * l_ - 0.7034186147 * m_ + 1.7076147010 * s_ return r, g, b end -- magic oklab stuff function linear_to_srgb(x) if x <= 0.0031308 then return 12.92 * x else return 1.055 * x^(1/2.4) - 0.055 end end -- magic oklab stuff function lch_to_rgb(L, C, h) local r, g, b = oklab_to_linear_srgb(lch_to_lab(L, C, h)) r = linear_to_srgb(r) g = linear_to_srgb(g) b = linear_to_srgb(b) return math.floor(r * max_value), math.floor(g * max_value), math.floor(b * max_value) end -- inverse converters local function rgb_to_hsl_or_hsv(r, g, b, return_hsv) r = r / max_value g = g / max_value b = b / max_value local max = math.max(r, g, b) local min = math.min(r, g, b) local h, s, lv = 0, 0, (max + min) / 2 local d = max - min if return_hsv then lv = max -- Value for HSV s = max == 0 and 0 or d / max else lv = (max + min) / 2 -- Lightness for HSL s = max == min and 0 or (lv > 0.5 and d / (2 - max - min) or d / (max + min)) end if max ~= min then if max == r then h = (g - b) / d + (g < b and 6 or 0) elseif max == g then h = (b - r) / d + 2 elseif max == b then h = (r - g) / d + 4 end h = h / 6 end return math.floor(h * 360), math.floor(s * 100), math.floor(lv * 100) end local function srgb_to_linear(c) if c <= 0.04045 then return c / 12.92 else return ((c + 0.055) / 1.055) ^ 2.4 end end local function rgb_to_linear_srgb(r, g, b) r = srgb_to_linear(r / max_value) g = srgb_to_linear(g / max_value) b = srgb_to_linear(b / max_value) return r, g, b end local function linear_srgb_to_oklab(r, g, b) local l = 0.4121656120 * r + 0.5362752080 * g + 0.0514575653 * b local m = 0.2118591070 * r + 0.6807189584 * g + 0.1074065790 * b local s = 0.0883097947 * r + 0.2818474174 * g + 0.6302613616 * b local l_ = l ^ (1 / 3) local m_ = m ^ (1 / 3) local s_ = s ^ (1 / 3) local L = 0.2104542553 * l_ + 0.7936177850 * m_ - 0.0040720468 * s_ local a = 1.9779984951 * l_ - 2.4285922050 * m_ + 0.4505937099 * s_ local b = 0.0259040371 * l_ + 0.7827717662 * m_ - 0.8086757660 * s_ return L, a, b end local function oklab_to_lch(L, a, b) local C = math.sqrt(a * a + b * b) local h if a == 0 then h = 0; else h = math.atan(b/a) * 180 / math.pi end if h < 0 then h = h + 360 end return math.floor(L*100), math.floor(C*100), math.floor(h) end local function rgb_to_oklab_lch(r, g, b) local lr, lg, lb = rgb_to_linear_srgb(r, g, b) local L, a, b1 = linear_srgb_to_oklab(lr, lg, lb) return oklab_to_lch(L, a, b1) end function convert_inverse(bars,prev_dropdown_index,new_dropdown_index) local r,g,b local x,y,z = tonumber(bars[1]),tonumber(bars[2]),tonumber(bars[3]) if prev_dropdown_index == "1" then -- rgb r,g,b = x,y,z else if prev_dropdown_index == "2" then -- hsv r,g,b = hsv_to_rgb(x/360,y/100,z/100) else if prev_dropdown_index == "3" then -- hsl r,g,b = hsl_to_rgb(x/360,y/100,z/100) else if prev_dropdown_index == "4" then -- oklab r,g,b = lch_to_rgb(x/100,y/100,z/360) end end end end if new_dropdown_index == "1" -- rgb then return r,g,b end if new_dropdown_index == "4" -- oklab then return rgb_to_oklab_lch(r,g,b) end -- assume the other possiblities are hsv and hsl return rgb_to_hsl_or_hsv(r,g,b,new_dropdown_index=="2") end