灰度图的心理学公式

红绿蓝三色是非常不直观的颜色表示的方法,如果不经过训练,人类几乎没有办法直接通过 RGB 的值来猜出大概的颜色来。而 HSB 是用来解决人眼感知问题的,它将颜色用色相、饱和度、明度来表示。

可是,即便是 HSB 也不能完美解决人眼的感知问题。看下图,黄色和蓝色的饱和度和明度一样,只是色相不同,你觉得哪一个颜色更亮,哪一个更暗?

rgb-example.png

相信大家都会觉得黄色更亮,蓝色总给人一种阴暗的感觉。

所以,在饱和度和明度之外,一定还有一种人眼对亮度的感觉是与色相相关的。

我们将不同色相的颜色排成一圈,观察下哪些颜色更亮,哪些更暗:

rgb-hex.png

我们将上面的不同颜色直接转成灰度图像,这是最能反映人眼感知的灰度图像,它将是这样的:

rgb-hex-example.png

也就是说,不同的颜色值总能找到一个人眼感知的灰度值,这是著名的心理学公式:

灰度 = 红×0.299 + 绿×0.587 + 蓝×0.114

在灰度背景色上决定前景色

一个图像的每一个像素经过上面的公式计算得到的新的图像,即是人眼感知亮度的灰度图。

于是,当我们期望计算一个能在背景色上清晰显示的前景色时,我们可将背景颜色转换为灰度颜色,然后根据灰度程度,选取黑色或白色作为前景色。

当然,如果你喜欢,可以将一段黑色或接近于黑色的灰度色作为浅色背景的前景;将一段白色或颉俊宇白色的灰度色作为深色背景的前景。

JavaScript代码实现

RGB 和 Hex 的互相转换:

// rgbToHex(0, 51, 255) => "#0033ff"
function rgbToHex(r, g, b) {
  return "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
}

//hexToRgb("#0033ff") => {r: 0, g: 51, b: 255}
//hexToRgb("#0033ff").g => 51
function hexToRgb(hex) {
  // Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF")
  var shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
  hex = hex.replace(shorthandRegex, function (m, r, g, b) {
    return r + r + g + g + b + b;
  });

  var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
  return result ? {
    r: parseInt(result[1], 16),
    g: parseInt(result[2], 16),
    b: parseInt(result[3], 16)
  } : null;
}

//灰度 = 红×0.299 + 绿×0.587 + 蓝×0.114
function getGrayLevelFromRgb(r, g, b) {
  return (0.299 * r + 0.587 * g + 0.114 * b) / 255;
}

// getGrayLevel('#167df0') => 0.4208352941176471
function getGrayLevel(hex) {
  var rgb = hexToRgb(hex);
  return getGrayLevelFromRgb(rgb.r, rgb.g, rgb.b);
}

function getColor(background_color) {
  var grayLevel = getGrayLevel(background_color);
  return grayLevel > 0.5 ? '#000000b3' : '#fff';
}

最后只需要 调用 getColor(background_color) 传入背景颜色,就可以自动输出符合背景颜色的字体颜色.

效果展示:

前景色展示.png

0条评论 顺序楼层
请先登录再回复