我正在寻找某种公式或算法来确定给定RGB值的颜色的亮度。我知道这不像把RGB值加在一起那么简单,更高的总和更亮,但我有点不知所措,不知道从哪里开始。


当前回答

基于所有这些答案,我的简单结论是,对于大多数实际用例,您只需要:

brightness = 0.2*r + 0.7*g + 0.1*b 

当r,g,b值在0到255之间时,亮度范围也在0(=黑)到255(=白)之间。

可以对它进行微调,但通常没有必要。

其他回答

我已经在接受的答案中对三种算法做了比较。我循环生成颜色,大约每400个颜色使用一次。每种颜色由2x2像素表示,颜色从最深到最浅(从左到右,从上到下)排序。

第一张图片-亮度(相对)

0.2126 * R + 0.7152 * G + 0.0722 * B

第二张图片- http://www.w3.org/TR/AERT#color-contrast

0.299 * R + 0.587 * G + 0.114 * B

第三张图片- HSP颜色模型

sqrt(0.299 * R^2 + 0.587 * G^2 + 0.114 * B^2)

第4张图- WCAG 2.0 SC 1.4.3相对亮度和对比度公式(见@Synchro的答案在这里)

根据一行中的颜色数量,有时可以在第一张和第二张图片上发现图案。我从第3或第4算法的图片上没有发现任何模式。

如果我必须选择,我会选择算法3,因为它更容易实现,比4快33%。

正如@Nils Pipenbrinck所提到的:

所有这些方程在实践中都很有效,但如果你需要非常精确,你就必须[做一些额外的gamma东西]。在深灰色中,忽略伽玛和正确伽玛之间的亮度差异高达20%。

这里有一个完全自包含的JavaScript函数,它做了“额外的”工作来获得额外的准确性。它基于Jive Dadson对这个问题的c++回答。

// Returns greyscale "brightness" (0-1) of the given 0-255 RGB values
// Based on this C++ implementation: https://stackoverflow.com/a/13558570/11950764
function rgbBrightness(r, g, b) {
  let v = 0;
  v += 0.212655 * ((r/255) <= 0.04045 ? (r/255)/12.92 : Math.pow(((r/255)+0.055)/1.055, 2.4));
  v += 0.715158 * ((g/255) <= 0.04045 ? (g/255)/12.92 : Math.pow(((g/255)+0.055)/1.055, 2.4));
  v += 0.072187 * ((b/255) <= 0.04045 ? (b/255)/12.92 : Math.pow(((b/255)+0.055)/1.055, 2.4));
  return v <= 0.0031308 ? v*12.92 : 1.055 * Math.pow(v,1.0/2.4) - 0.055;
}

请参阅Myndex的答案以获得更准确的计算。

把这看作是对Myndex的精彩回答的补充。正如他(和其他人)解释的那样,计算RGB颜色的相对亮度(和感知亮度)的算法是设计用于线性RGB值的。你不能只是将它们应用到原始sRGB值上,并希望得到相同的结果。

理论上,这一切听起来都很棒,但我真的需要亲眼看看证据,所以,受到彼得·赫塔克(Petr Hurtak)的颜色渐变的启发,我自己做了一个。它们说明了两种最常见的算法(ITU-R建议BT.601和BT.709),并清楚地说明了为什么应该使用线性值(而不是伽玛校正值)进行计算。

首先,下面是旧的ITU BT.601算法的结果。左边的使用原始sRGB值。右边的使用线性值。

ITU-R BT.601颜色亮度梯度

0.299 r + 0.587 g + 0.114 b

在这个分辨率下,左边的照片实际上看起来非常好!但如果你仔细观察,你会发现一些问题。在更高的分辨率下,不需要的人工制品更加明显:

线性的不受这些影响,但是有很多干扰。让我们将其与ITU-R建议BT.709进行比较……

ITU-R BT.709颜色亮度梯度

0.2126 r + 0.7152 g + 0.0722 b

哦男孩。显然不打算与原始sRGB值一起使用!然而,这正是大多数人所做的!

在高分辨率下,你可以真正看到这个算法在使用线性值时是多么有效。它没有之前那个那么多噪音。虽然这些算法都不是完美的,但这个算法已经是最好的了。

请定义亮度。如果你想知道颜色有多接近白色你可以用欧几里得距离(255,255,255)

为了清晰起见,使用平方根的公式必须是

√(系数* (colour_value^2))

not

√(系数*颜色值)^2

证明这一点的证据在于将R=G=B三位一体转换为灰度R。只有当你将颜色值平方,而不是颜色值乘以系数时,这才成立。参见灰色的九种色调