local module = {}
local getArgs = require('Module:Arguments').getArgs
local Color = require('Module:color')
function toString(r, g, b, format)
function toHex(num)
local int, float = math.modf(num)
if float > 0.4 then int = int + 1 end
local zero = ''
if int < 16 then zero = '0' end
return zero..string.format('%X', int)
end
r = math.floor(r + 0.5)
g = math.floor(g + 0.5)
b = math.floor(b + 0.5)
format = format or 'hex'
if format == 'rgba' then
return 'rgba('..r..','..g..','..b..',0.8)'
elseif format == 'hex' then
return toHex(r)..toHex(g)..toHex(b)
end
end
function l2limit(l2, max, min)
if l2 > max then l2 = max end
if l2 < min then l2 = min end
return l2
end
function tCalc(h , k1 , k2 , k3 , l2 , c)
local c1 , c2 , c3 = nil
if l2 < (k1 + k2 * h ^ 2) * c ^ 2 then
c1 = (l2 / (k1 + k2 * h ^ 2)) ^ (1/2)
c2 = c1 * h
c3 = 0
elseif l2 > k1 * 65025 + k2 * (255 - c + h * c) ^ 2 + k3 * (255 - c) ^ 2 then
local A = k2 * (1 - h) ^ 2+ k3
c3 = ((A * l2 / 65025 - k1 * A - k2 * k3 * h ^ 2) ^ (1/2) - k2 * h * (1 - h)) * 255 / A
c2 = (255 - c3) * h + c3
c1 = 255
else
local B = k1 + k2 * h
c3 = ((B ^ 2 - k1 - k2 * h ^ 2) * c ^ 2 + l2) ^ (1/2) - B * c
c2 = c * h + c3
c1 = c + c3
end
return {c1 , c2 , c3}
end
function lmrCalc(rgb , l2 , t)
local h1 = (255 - rgb[1])/(765 - rgb[1] - rgb[2] - rgb[3])
local h2 = (255 - rgb[2])/(765 - rgb[1] - rgb[2] - rgb[3])
local h3 = (255 - rgb[3])/(765 - rgb[1] - rgb[2] - rgb[3])
local A = 0.2126 * h1 ^ 2 + 0.7152 * h2 ^ 2 + 0.0722 * h3 ^ 2
local B = 0.2126 * h1 + 0.7152 * h2 + 0.0722 * h3
local X = (B - (A / t * (l2 / 65025 - 1) + B ^ 2) ^ (1/2)) * 255 / A
local Y = (B - (A / t ^ 2 * (l2 / 65025 - 1) + B ^ 2) ^ (1/2)) * 255 / A
local Z = (B - (A / t ^ 3 * (l2 / 65025 - 1) + B ^ 2) ^ (1/2)) * 255 / A
return toString(255-h1*X , 255-h2*X , 255-h3*X) , toString(255-h1*Y , 255-h2*Y , 255-h3*Y) , toString(255-h1*Z , 255-h2*Z , 255-h3*Z , 'rgba')
end
function module.main(frame)
local color_T , col_t , col_l , col_m , col_r , h = nil
local args = getArgs(frame)
local a = {args["LtMAG"] or 1 , args["ChrMAG"] or 3 , args['LtMAX'] or 225 , args['LtMIN'] or 0 , (args['ChrMAX'] or 200)/200 , args['Tint'] or 2}
local color = Color.create(args[1]):rgb().value
local r , g , b = color[1] , color[2] , color[3]
local l2 = l2limit(a[1]^2*(0.2126*r^2+0.7152*g^2+0.0722*b^2) , a[3]^2 , a[4]^2)
if l2>=65025 then
col_t , col_l , col_m , col_r = 'FFFFFF' , 'FFFFFF' , 'FFFFFF' , 'rgba(255,255,255,0.8)'
else
if r>g then
if g>b then --rgb 0~60
h = (g - b)/(r - b)
color_T = tCalc(h , 0.2126 , 0.7152 , 0.0722 , l2 , math.min(a[2]*(r-b) , a[5]*(-1286.9*h^4+1328.7*h^3-142.29*h^2+134.23*h+165.74) , 255))
elseif b>r then --brg 240~300
h = (r - g)/(b - g)
color_T = tCalc(h , 0.0722 , 0.2126 , 0.7152 , l2 , math.min(a[2]*(b-g) , a[5]*(-53.74*h^2+37.053*h+129.88) , 255))
color_T = {color_T[2] , color_T[3] , color_T[1]}
else --rbg 300~360
h = (r - b)/(r - g)
color_T = tCalc(1-h , 0.2126 , 0.0722 , 0.7152 , l2 , math.min(a[2]*(r-g) , a[5]*(-49.395*h^2+101.94*h+113.19) , 255))
color_T = {color_T[1] , color_T[3] , color_T[2]}
end
else
if r>b then --grb 60~120
h = (g - r)/(g - b)
color_T = tCalc(1-h , 0.7152 , 0.2126 , 0.0722 , l2 , math.min(a[2]*(g-b) , a[5]*(29.76*h^2-104.35*h+199.48) , 255))
color_T = {color_T[2] , color_T[1] , color_T[3]}
elseif b>g then --bgr 180~240
h = (b - g)/(b - r)
color_T = tCalc(1-h , 0.0722 , 0.7152 , 0.2126 , l2 , math.min(a[2]*(b-r) , a[5]*(-1436.6*h^4+3559.6*h^3-2760.2*h^2+379.84*h+387.24) , 255))
color_T = {color_T[3] , color_T[2] , color_T[1]}
elseif g>r then --gbr 120~180
h = (b - r)/(g - r)
color_T = tCalc(h , 0.7152 , 0.0722 , 0.2126 , l2 , math.min(a[2]*(g-r) , a[5]*(-1404.8*h^4+2509.9*h^3-1063.4*h^2+220.65*h+124.89) , 255))
color_T = {color_T[3] , color_T[1] , color_T[2]}
else --r=g=b c=0
color_T = tCalc(0 , 1 , 0 , 0 , l2 , 0)
end
end
col_t = toString(color_T[1] , color_T[2] , color_T[3])
col_l , col_m , col_r = lmrCalc(color_T , l2 , a[6])
end
frame:callParserFunction('#vardefine' , 'color-t' , col_t)
frame:callParserFunction('#vardefine' , 'color-l' , col_l)
frame:callParserFunction('#vardefine' , 'color-m' , col_m)
frame:callParserFunction('#vardefine' , 'color-r' , col_r)
if args['output']=='orig' then
return toString(r, g, b)
else
return col_t
end
end
return module