Module talk:Color
求助,脚本出错
在此模块的控制台:
=p.create("hsl(123,45%,67%)"):toString('hex')
回溯:
- (tail call): ?
- 模块:Color:394: 在函数“hsl2rgb”中
- 模块:Color:428: 在函数“rgb”中
- 模块:Color:651: 在函数“toString”中
- 控制台输入:16: ?
- (tail call): ?
- [C]: 在函数“xpcall”中
- MWServer.lua:99: 在函数“handleCall”中
- MWServer.lua:313: 在函数“dispatch”中
- MWServer.lua:52: 在函数“execute”中
- mw_main.lua:7: 在主块中
- [C]: ?
@東東君
--
页面User:DGCK81LNN/签名/style.css没有内容。
DGCK81LNN新圈名:纯真灵魂
用户页 | 讨论 | 贡献
奇怪的签名增加了! 2020年5月31日 (日) 15:39 (CST)
亮暗色判断改为通过计算比较与黑白色的对比度比例(contrast ratio)实现
原理
现有的实现是通过直接与HTML灰色rgb(127.5, 127.5, 127.5)的灰度值比较,然而人眼对颜色亮度的反应是非线性的。根据WCAG 2.x技术标准,判断前后景色彩搭配是否符合观感的判据是颜色对比度比例(contrast ratio),这里是一个计算工具:contrastchecker
一个例子是,考虑#777的亮暗色。根据WCAG 2.x技术标准,#777, #000的对比度4.68要比#FFF, #777的4.47更高,所以#777是亮色(而非因为比HTML灰色#808080更暗就属于暗色)。然而根据下文所述的APCA标准又恰恰相反:#FFF, #999的对比度54.6要比#999, #000的49.4更高,所以#999反而又是暗色了。我不好说
实现
根据WCAG 2.x技术标准,颜色对比度比例(contrast ratio)是一个[1,21]间的比值(写作1:1~21:1),其中两色同色时取1,一黑一白时取21。
颜色对比度比例定义为(LY_1+0.05)/(LY_2+0.05),或取其倒数。其中LY是相对亮度,根据下式定义:——以上未签名(注)本条留言未签名,留言后请记得用--~~~~签名!的留言由苛性氢(讨论·贡献)于2022年3月4日 (五) 07:35 (UTC+8)添加。
For the sRGB colorspace, the relative luminance of a color is defined as L = 0.2126 * R + 0.7152 * G + 0.0722 * B where R, G and B are defined as:
if RsRGB <= 0.03928 then R = RsRGB/12.92 else R = ((RsRGB+0.055)/1.055) ^ 2.4 if GsRGB <= 0.03928 then G = GsRGB/12.92 else G = ((GsRGB+0.055)/1.055) ^ 2.4 if BsRGB <= 0.03928 then B = BsRGB/12.92 else B = ((BsRGB+0.055)/1.055) ^ 2.4
and RsRGB, GsRGB, and BsRGB are defined as:
RsRGB = R8bit/255 GsRGB = G8bit/255 BsRGB = B8bit/255
此外,此处给出了更新的WCAG 3 APCA标准,这里是它的计算工具,不过公式较为复杂:APCA
结论
提请将亮暗色判断改为通过在WCAG 2.x(或者3)技术标准下,计算给定颜色与黑白色的对比度比例,并比较取两者间较小的一方实现。
易推得,即为比较给定颜色的相对亮度L值与“中性灰”的相对亮度LY_gray=sqrt(0.05*1.05)-0.05,大为亮色,小为暗色。话说这个“中性灰”计算回来是rgb(117.38, 117.38, 117.38)即#757575啊……——以上未签名(注)本条留言未签名,留言后请记得用--~~~~签名!的留言由苛性氢(讨论·贡献)于2022年3月4日 (五) 07:35 (UTC+8)添加。
参考
Visual Contrast of Text Subgroup
苛性氢(讨论) 2022年3月2日 (三) 22:33 (CST)
- 赞 您可以在测试完成后直接修改模块,如果没有权限编辑,可以先去讨论版申请萌娘百科:技术编辑员的身份。--東東君(讨论) 2022年3月3日 (四) 10:12 (CST)
- 由于不满足申请条件(我其实不怎么会用Lua,毕竟不是科班的嘛,献丑了233),提请将原Color.isLight()由:
function Color.isLight(this)
local rgb = this:rgb().value
return 0.213 * rgb[1] + 0.715 * rgb[2] + 0.072 * rgb[3] > 255 / 2
end
- 修改为2.x标准的
--[[
@desc Gamma校正
@param {number} r_g_b
@return {number}
]]
function adjustGamma(r_g_b)
if r_g_b <= 0.04045 then return r_g_b / 12.92
else return ((r_g_b + 0.055) / 1.055) ^ 2.4 end
end
--[[
@desc 获得颜色的相对亮度
@param {Color} this
@return {number}
]]
function Color.getRelativeLuminance(this)
local rgb = this:rgb().value
return 0.2126 * adjustGamma(rgb[1] / 255) +
0.7152 * adjustGamma(rgb[2] / 255) +
0.0722 * adjustGamma(rgb[3] / 255)
end
--[[
@desc 获得两颜色的对比度比例
@param {Color} this
@param {Color} color
@return {number}
]]
function Color.getContrastRatio(this, color)
local ratio = (this:getRelativeLuminance() + 0.05) / (color:getRelativeLuminance() + 0.05)
if ratio < 1 then return 1 / ratio
else return ratio end
end
--[[
@desc 检测一个颜色是否为亮色
@param {Color} this
@return {boolean}
]]
function Color.isLight(this)
return this:getRelativeLuminance() > (0.05 * 1.05) ^ 0.5 - 0.05
end
请求hsl->rgb添加h mod360
输入的颜色h值可能不是标准的[0,360)范围,而且模块内rgb->hsl本身就会四舍五入出h=360。
{{ColorOps|s+0|#E34E4F}}
->
- E34F4F