网页是如何变灰的

纯技术探讨。
0.目录
光的三原色、灰色和灰阶算法
HTML和CSS
套用全局CSS filter使网页变灰
1 光的三原色、灰色和灰阶算法
1.1 光的三原色
初中物理告诉我们光的三原色是红绿蓝,颜料的三原色是红黄蓝(印刷业界是品红/黄/青+黑)。由于显色原理不同,光的三原色是一个加色模型(等量的红、绿、蓝在混合之后输出的颜色是白色),而颜料的三原色是一个减色模型。

显示器发光自然靠的是光,因此适用光的三原色模型。一台色域为sRGB的显示器,在红、绿、蓝三个维度上分别能发出0-255级的光。当红、绿、蓝三种光线的强度都为255(最亮)时,显示器理论上应该显示纯白色。
1.2 灰色

用(x, y, z)分别描述某一个给定颜色当中的红、绿、蓝色的数值。(0, 0, 0)代表纯黑色,(255, 255, 255)代表纯白色,那么(a, a, a)(其中0<a<255)是什么颜色?
对,都是灰色,不同程度的灰色。
那么如果通过某种算法可以将一张彩色的图像转换为灰阶图像(grayscale image, 仅含有灰色的图像),这种算法就统称为灰阶算法。
1.3 灰阶算法
灰阶算法只是一类算法的统称。它的作用是把图像上每一个像素【RGB=(x,y,z)】通过一定的处理,映射成为一个灰色像素点【RGB=(a,a,a)】。
完成这种映射的算法千奇百怪。目前比较常用的一种计算灰度取值(即上文中的参数a)的算法是:
Gray = (Red * 0.2989 + Green * 0.5870 + Blue * 0.1140)
其中0.2989、0.5870和0.1140都是经验参数:俺不知道为什么,但俺寻思这个值能用。
另外一些算法有暴力平均法、去饱和法(转换为HSL模型后设置饱和度0)等等。它们最终的目的都是一样的:将给定内容中全部像素点映射为灰色像素点,实现整体内容的灰度处理。
2 HTML和CSS
2.1 HTML
HTML(HyperText Markup Language, 超文本标记语言)是一种标记语言(不是编程语言)。一个HTML文档(一个网页)由层层嵌套的标签组成。纯HTML只告诉浏览器“我这个网页上有哪些内容”,比如“一只青蛙一张嘴,两只眼睛四条腿”就描述了青蛙的结构:眼睛×2,嘴,腿×4.
2.2 CSS
层叠样式表(Cascading Style Sheet)通常与HTML一起使用(在目前的大部分网站来说算是官配cp了)。它可以为HTML文档中出现的标签添加额外的描述,比如颜色、形状、大小。

3 CSS filter
在CSS规范当中,有一类比较特殊的规则“滤镜(filters)”,一般用于处理图像。跟大部分人认知中的滤镜功能一样,滤镜可以改变图像的一些属性,比如灰度、亮度、阴影、颜色反转和模糊。
“灰度”这一函数的标准语法是:
filter: grayscale(0-1取值或0%-100%)
它可以把一张彩色图像通过灰度算法映射为一张灰度图像。
如果在WebStorm或者类似的面向网页前端的编辑器中使用,编辑器会自动补全几种针对不同浏览器的语法。所以一般通过审查元素看到的内容会是下面的样子:
-webkit-filter: grayscale(100%);
-moz-filter: grayscale(100%);
-ms-filter: grayscale(100%);
-o-filter: grayscale(100%);
filter: grayscale(100%);
类比Photoshop中的图层,在一个网页当中,不同的元素也有不同的叠放顺序和主次之分。要使这个灰色滤镜对整个网站上的内容都生效,有两种思路:
为主div中添加filter: grayscale。
为html标签或body标签添加filter: grayscale。但是如果直接在body标签中添加的话,position: fixed这条属性就会失效。所以个人建议尽可能地在html标签中添加。
4. 参考/扩展阅读
1. 光と色の三原色 色が見える仕組み(7): 光と色と:http://optica.cocolog-nifty.com/blog/2012/04/post-ab6f.html
2. 6种图片灰度转换算法:https://github.com/aooy/blog/issues/4
3. filter - CSS(层叠样式表) | MDN:https://developer.mozilla.org/zh-CN/docs/Web/CSS/filter