跳转到内容

模組:Infobox color

维基百科,自由的百科全书
文档图示 模块文档[创建]
-- 若程式碼有問題可以直接修改
function kv(s, k)
	return s:sub(k, k)
end

function rd(n)
	return math.floor(n + 0.5)
end

local hex12, hex, rgb, cmy, cmyk, hsl, hsv, hwb
hex = {
	hex12 = function(h)
		return #h == 6 and kv(h, 1) .. kv(h, 3) .. kv(h, 5) or h
	end,
	hex = function(h)
		return #h == 3 and kv(h, 1) .. kv(h, 1) .. kv(h, 2) .. kv(h, 2) .. kv(h, 3) .. kv(h, 3) or h
	end,
	rgb = function(h)
		local s3 = function(c)
			return 0x11 * tonumber('0x' .. kv(h, c))
		end
		local s6 = function(c)
			return tonumber('0x' .. kv(h, c * 2 - 1) .. kv(h, c * 2))
		end
		local f = #h == 4 and s3 or s6
		return f(1), f(2), f(3)
	end,
	cmy = function(h)
		return rgb.cmy(hex.rgb(h))
	end,
	cmyk = function(h)
		return rgb.cmyk(hex.rgb(h))
	end,
	hsl = function(h)
		return rgb.hsl(hex.rgb(h))
	end,
	hsv = function(h)
		return rgb.hsv(hex.rgb(h))
	end,
	hwb = function(h)
		return rgb.hwb(hex.rgb(h))
	end
}
hex12 = hex
rgb = {
	hex12 = function(r, g, b)
		return hex.hex12(rgb.hex(r, g, b))
	end,
	hex = function(r, g, b)
		local f = function(c)
			return string.format("%x", rd(c))
		end
		return f(r) .. f(g) .. f(b)
	end,
	rgb = function(r, g, b)
		return r, g, b
	end,
	cmy = function(r, g, b)
		return 255 - r, 255 - g, 255 - b
	end,
	cmyk = function(r, g, b)
		return cmy.cmyk(rgb.cmy(r, g, b))
	end,
	hsl = function(r, g, b)
		return hsv.hsl(rgb.hsv(r, g, b))
	end,
	hsv = function(r, g, b)
		local h, s, v
		local p = math.max(r, g, b)
		local q = math.min(r, g, b)
		local f = function(x, y)
			return 60 * (x - y) / (p - q)
		end
		if p == q then
			h = 0
		elseif p == r then
			h = f(g, b) + 360
			h = h % 360
		elseif p == g then
			h = f(b, r) + 120
		else
			h = f(r, g) + 240
		end
		s = p == 0 and 0 or (1 - q / p)
		v = p / 255
		return h, s, v
	end,
	hwb = function(r, g, b)
		return hsv.hwb(rgb.hsv(r, g, b))
	end
}
cmy = {
	hex12 = function(c, m, y)
		return rgb.hex12(cmy.rgb(c, m, y))
	end,
	hex = function(c, m, y)
		return rgb.hex(cmy.rgb(c, m, y))
	end,
	rgb = function(c, m, y)
		return 255 - c, 255 - m, 255 - y
	end,
	cmy = function(c, m, y)
		return c, m, y
	end,
	cmyk = function(c, m, y)
		local k = math.min(c, m, y)
		local f = function(c)
			return (c - k) / (255 - k) * 255
		end
		if k == 255 then
			return 0, 0, 0, 255
		else
			return f(c), f(m), f(y), k
		end
	end,
	hsl = function(c, m, y)
		return rgb.hsl(cmy.rgb(c, m, y))
	end,
	hsv = function(c, m, y)
		return rgb.hsv(cmy.rgb(c, m, y))
	end,
	hwb = function(c, m, y)
		return rgb.hwb(cmy.rgb(c, m, y))
	end
}
cmyk = {
	hex12 = function(c, m, y, k)
		return cmy.hex12(cmyk.cmy(c, m, y, k))
	end,
	hex = function(c, m, y, k)
		return cmy.hex(cmyk.cmy(c, m, y, k))
	end,
	rgb = function(c, m, y, k)
		return cmy.rgb(cmyk.cmy(c, m, y, k))
	end,
	cmy = function(c, m, y, k)
		local f = function(c)
			return c * (255 - k) / 255 + k
		end
		return f(c), f(m), f(y)
	end,
	cmyk = function(c, m, y, k)
		return c, m, y, k
	end,
	hsl = function(c, m, y, k)
		return cmy.hsl(cmyk.cmy(c, m, y, k))
	end,
	hsv = function(c, m, y, k)
		return cmy.hsv(cmyk.cmy(c, m, y, k))
	end,
	hwb = function(c, m, y, k)
		return cmy.hwb(cmyk.cmy(c, m, y, k))
	end
}
hsl = {
	hex12 = function(h, s, l)
		return hsv.hex12(hsl.hsv(h, s, l))
	end,
	hex = function(h, s, l)
		return hsv.hex(hsl.hsv(h, s, l))
	end,
	rgb = function(h, s, l)
		return hsv.rgb(hsl.hsv(h, s, l))
	end,
	cmy = function(h, s, l)
		return hsv.cmy(hsl.hsv(h, s, l))
	end,
	cmyk = function(h, s, l)
		return hsv.cmyk(hsl.hsv(h, s, l))
	end,
	hsl = function(h, s, l)
		return h, s, l
	end,
	hsv = function(h, s, l)
		local v = l + s * math.min(l, 1 - l)
		local sv = v == 0 and 0 or 2 * (1 - l / v)
		return h, sv, v
	end,
	hwb = function(h, s, l)
		return hsv.hwb(hsl.hsv(h, s, l))
	end
}
hsv = {
	hex12 = function(h, s, v)
		return rgb.hex12(hsv.rgb(h, s, v))
	end,
	hex = function(h, s, v)
		return rgb.hex(hsv.rgb(h, s, v))
	end,
	rgb = function(h, s, v)
		local hi = math.floor(h / 60)
		local f = h / 60 - hi
		local p = v * (1 - s)
		local q = v * (1 - f * s)
		local t = v * (1 - (1 - f) * s)
		local ff = function(r, g, b)
			return r * 255, g * 255, b * 255
		end
		if hi == 0 then
			return ff(v, t, p)
		elseif hi == 1 then
			return ff(q, v, p)
		elseif hi == 2 then
			return ff(p, v, t)
		elseif hi == 3 then
			return ff(p, q, v)
		elseif hi == 4 then
			return ff(t, p, v)
		else
			return ff(v, p, q)
		end
	end,
	cmy = function(h, s, v)
		return rgb.cmy(hsv.rgb(h, s, v))
	end,
	cmyk = function(h, s, v)
		return rgb.cmyk(hsv.rgb(h, s, v))
	end,
	hsl = function(h, s, v)
		local l = v * (1 - s / 2)
		local sl = (l == 0 or l == 1) and 0 or (v - l) / math.min(l, 1 - l)
		return h, sl, l
	end,
	hsv = function(h, s, v)
		return h, s, v
	end,
	hwb = function(h, s, v)
		return h, (1 - s) * v, 1 - v
	end
}
hwb = {
	hex12 = function(h, w, b)
		return hsv.hex12(hwb.hsv(h, w, b))
	end,
	hex = function(h, w, b)
		return hsv.hex(hwb.hsv(h, w, b))
	end,
	rgb = function(h, w, b)
		return hsv.rgb(hwb.hsv(h, w, b))
	end,
	cmy = function(h, w, b)
		return hsv.cmy(hwb.hsv(h, w, b))
	end,
	cmyk = function(h, w, b)
		return hsv.cmyk(hwb.hsv(h, w, b))
	end,
	hsl = function(h, w, b)
		return hsv.hsl(hwb.hsv(h, w, b))
	end,
	hsv = function(h, w, b)
		return h, b == 1 and 0 or (1 - w / (1 - b)), 1 - b
	end,
	hwb = function(h, w, b)
		return h, w, b
	end
}

local colorsort = {'hex12', 'hex', 'rgb', 'cmy', 'cmyk', 'hsl', 'hsv', 'hwb'}
local colorconvert = {
	hex12 = hex12,
	hex = hex,
	rgb = rgb,
	cmy = cmy,
	cmyk = cmyk,
	hsl = hsl,
	hsv = hsv,
	hwb = hwb
}

local colorload = {
	hex12 = function(args)
		return args[1]
	end,
	hex = function(args)
		return args[1]
	end,
	rgb = function(args)
		return tonumber(args[1]), tonumber(args[2]), tonumber(args[3])
	end,
	cmy = function(args)
		return tonumber(args[1]) * 2.55, tonumber(args[2]) * 2.55, tonumber(args[3]) * 2.55
	end,
	cmyk = function(args)
		return tonumber(args[1]) * 2.55, tonumber(args[2]) * 2.55, tonumber(args[3]) * 2.55, tonumber(args[4]) * 2.55
	end,
	hsl = function(args)
		return tonumber(args[1]), tonumber(args[2]) / 100, tonumber(args[3]) / 100
	end,
	hsv = function(args)
		return tonumber(args[1]), tonumber(args[2]) / 100, tonumber(args[3]) / 100
	end,
	hwb = function(args)
		return tonumber(args[1]), tonumber(args[2]) / 100, tonumber(args[3]) / 100
	end
}

local colorformat = {
	hex12 = function(h)
		return h
	end,
	hex = function(h)
		return h
	end,
	rgb = function(r, g, b)
		return '(' .. rd(r) .. ', ' .. rd(g) .. ', ' .. rd(b) .. ')'
	end,
	cmy = function(c, m, y)
		return '(' .. rd(c / 2.55) .. ', ' .. rd(m / 2.55) .. ', ' .. rd(y / 2.55) .. ')'
	end,
	cmyk = function(c, m, y, k)
		return '(' .. rd(c / 2.55) .. ', ' .. rd(m / 2.55) .. ', ' .. rd(y / 2.55) .. ', ' .. rd(k / 2.55) .. ')'
	end,
	hsl = function(h, s, l)
		return '(' .. rd(h) .. '°, ' .. rd(s * 100) .. '%, ' .. rd(l * 100) .. '%)'
	end,
	hsv = function(h, s, v)
		return '(' .. rd(h) .. '°, ' .. rd(s * 100) .. '%, ' .. rd(v * 100) .. '%)'
	end,
	hwb = function(h, w, b)
		return '(' .. rd(h) .. '°, ' .. rd(w * 100) .. '%, ' .. rd(b * 100) .. '%)'
	end
}

function frameinput(frame, outmod)
	local args = require('Module:Arguments').getArgs(frame)
	local mod = string.lower(args.mod or 'rgb')
	mod = colorconvert[mod] == nil and 'rgb' or mod
	return colorformat[outmod](colorconvert[mod][outmod](colorload[mod](args)))
end

local p = {
	hex12 = function(frame)
		return frameinput(frame, 'hex12')
	end,
	hex = function(frame)
		return frameinput(frame, 'hex')
	end,
	rgb = function(frame)
		return frameinput(frame, 'rgb')
	end,
	cmy = function(frame)
		return frameinput(frame, 'cmy')
	end,
	cmyk = function(frame)
		return frameinput(frame, 'cmyk')
	end,
	hsl = function(frame)
		return frameinput(frame, 'hsl')
	end,
	hsv = function(frame)
		return frameinput(frame, 'hsv')
	end,
	hwb = function(frame)
		return frameinput(frame, 'hwb')
	end
}

return p