Module:Module:LuminanceChroma to sRGB
Appearance
-- Module:LuminanceChroma to sRGB
-- Converts:
-- Luminance (%)
-- Chroma angle (degrees)
-- Chroma (%)
-- to sRGB hex
-- Preserves luminance
-- Output:
-- hex (default)
-- swatch
local p = {}
------------------------------------------------
-- Clamp helper
------------------------------------------------
local function clamp(x, min, max)
if x < min then return min end
if x > max then return max end
return x
end
------------------------------------------------
-- Convert sRGB (0-1) to hex
------------------------------------------------
local function rgbToHex(r, g, b)
r = clamp(math.floor(r * 255 + 0.5), 0, 255)
g = clamp(math.floor(g * 255 + 0.5), 0, 255)
b = clamp(math.floor(b * 255 + 0.5), 0, 255)
return string.format("#%02X%02X%02X", r, g, b)
end
------------------------------------------------
-- HSL → sRGB conversion
-- L = luminance (0–1)
-- C = chroma (0–1)
-- H = hue angle (degrees)
------------------------------------------------
local function hslToRgb(L, C, H)
H = H % 360
local Hp = H / 60
local X = C * (1 - math.abs((Hp % 2) - 1))
local r1, g1, b1 = 0, 0, 0
if Hp >= 0 and Hp < 1 then
r1, g1, b1 = C, X, 0
elseif Hp < 2 then
r1, g1, b1 = X, C, 0
elseif Hp < 3 then
r1, g1, b1 = 0, C, X
elseif Hp < 4 then
r1, g1, b1 = 0, X, C
elseif Hp < 5 then
r1, g1, b1 = X, 0, C
else
r1, g1, b1 = C, 0, X
end
local m = L - C/2
return r1 + m, g1 + m, b1 + m
end
------------------------------------------------
-- Main entry
------------------------------------------------
function p.convert(frame)
local args = frame.args
local L = tonumber(args.L)
local H = tonumber(args.H)
local C = tonumber(args.C)
local format = args.format or "hex"
if not L or not H or not C then
return "Error: L, H, and C must be numeric."
end
------------------------------------------------
-- Normalize input
------------------------------------------------
L = clamp(L, 0, 100) / 100
C = clamp(C, 0, 100) / 100
H = H % 360
------------------------------------------------
-- Convert
------------------------------------------------
local R, G, B = hslToRgb(L, C, H)
-- Final clamp
R = clamp(R, 0, 1)
G = clamp(G, 0, 1)
B = clamp(B, 0, 1)
local hex = rgbToHex(R, G, B)
if format == "swatch" then
return string.format(
'<span style="display:inline-block;width:1.5em;height:1.5em;border:1px solid #000;background-color:%s;vertical-align:middle;margin-right:0.4em;"></span><code>%s</code>',
hex,
hex
)
end
return "#" .. string.sub(hex, 2)
end
return p