Module:Hex to HSV
Jump to navigation
Jump to search
Documentation for this module may be created at Module:Hex to HSV/doc
--takes in a hex color and outputs an h,s,v
--ex. #619037 -> 092,062,056
local p = {}
function p.main(frame)
local hex = frame.args[1]
--strip away # and spaces from our string, we don't want it
hex = string.gsub(hex, '#', '')
hex = string.gsub(hex, ' ', '')
--confirm that our input is a valid hex number 6 characters long. Return -1 if not
if (#hex ~= 6 or tonumber(hex, 16) == nil) then
return -1
end
--Convert every 2 digits from hex to integer, then convert to percentage of the maximum amount (255)
local red = tonumber(string.sub(hex, 1,2), 16)/255
local green = tonumber(string.sub(hex, 3,4), 16)/255
local blue = tonumber(string.sub(hex, 5,6), 16)/255
local H,S,V
--Value is simply the maximum value of our colors
V = math.max(red, green, blue)
--The formula for Hue depends on which of our colors has the greatest value. Since we already calculated that as V, we can reuse the variable
if V == math.min(red, green, blue) then
-- if all colors are equal, we're just going to stick H at 0 to avoid a NaN
H = 0
elseif V == red then
H = (green - blue) / (red - math.min(green, blue))
elseif V == green then
H = 2 + (blue - red) / (green - math.min(red, blue))
else
H = 4 + (red - green) / (blue - math.min(red, green))
end
--Convert Hue to a positive degree measurement on the color wheel
H = H * 60
if H<0 then
H = H + 360
end
--We're reusing V as our maximum color value again for calculating saturation
--Only do the formula if V is not equal to 0 to avoid a divide-by-zero error
if V ~= 0 then
S = (V - math.min(red, green, blue)) / V
else
S = 0
end
--We no longer need these as percentages, and they suit our final purposes better as integers
S = S * 100
V = V * 100
--Concatenate HSV into a comma-separated string, with each segment being left-padded with 0s to have 3 digits and no decimals.
--This allows it to be sorted as a number
return string.format('%03.0f',H)..','..string.format('%03.0f',S)..','..string.format('%03.0f',V)
end
return p