2023年政策修订增补工作正在进行中,欢迎参与!
  • Moegirl.ICU:萌娘百科流亡社群 581077156(QQ),欢迎对萌娘百科运营感到失望的编辑者加入
  • Moegirl.ICU:账号认领正在试运行,有意者请参照账号认领流程

Module talk:Color

萌娘百科,万物皆可萌的百科全书!转载请标注来源页面的网页链接,并声明引自萌娘百科。内容不可商用。
跳转到导航 跳转到搜索

求助,脚本出错

在此模块的控制台:

=p.create("hsl(123,45%,67%)"):toString('hex')

Lua错误 第394行:attempt to compare number with string

回溯:

  1. (tail call): ?
  2. 模块:Color:394: 在函数“hsl2rgb”中
  3. 模块:Color:428: 在函数“rgb”中
  4. 模块:Color:651: 在函数“toString”中
  5. 控制台输入:16: ?
  6. (tail call): ?
  7. [C]: 在函数“xpcall”中
  8. MWServer.lua:99: 在函数“handleCall”中
  9. MWServer.lua:313: 在函数“dispatch”中
  10. MWServer.lua:52: 在函数“execute”中
  11. mw_main.lua:7: 在主块中
  12. [C]: ?

@東東君

--

页面User:DGCK81LNN/签名/style.css没有内容。

DGCK81LNN新圈名:纯真灵魂
用户页 | 讨论 | 贡献
奇怪的签名增加了!
2020年5月31日 (日) 15:39 (CST)

已修复(大概) --東東君讨论) 2020年5月31日 (日) 18:52 (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)添加。

参考

Relative luminance

Visual Contrast of Text Subgroup

苛性氢讨论) 2022年3月2日 (三) 22:33 (CST)

Like 您可以在测试完成后直接修改模块,如果没有权限编辑,可以先去讨论版申请萌娘百科:技术编辑员的身份。--東東君讨论) 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
此外对原实现部分作出如下更正:Gamma校正阈值改为0.04045,相对亮度符号由L改为Y。
已使用在线编译器(在有限的测试样例中)如期运行。至于注释和代码风格实在无能为力确保正确,就烦请协助啦,thanks
——苛性氢讨论) 2022年3月4日 (五) 07:16 (CST)
已添加代码。--東東君讨论) 2022年3月4日 (五) 18:51 (CST)

请求hsl->rgb添加h mod360

输入的颜色h值可能不是标准的[0,360)范围,而且模块内rgb->hsl本身就会四舍五入出h=360。

{{ColorOps|s+0|#E34E4F}} ->

  1. E34F4F

—— Grandom 2022年6月21日 (二) 14:21 (CST)

Ping一下. @東東君Bhsd —— Grandom 2022年6月23日 (四) 20:12 (CST)

已添加,本来是昨天就已经加上的,写完回复一提交就waf了--東東君讨论) 2022年6月24日 (五) 12:29 (CST)