Module:Hex to HSV

From Official Temtem Wiki
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