CSS filter与前端滤镜

栏目: IT技术 · 发布时间: 4年前

内容简介:今天(2020.04.04)很多网站都换成了灰色调,如淘宝百度掘金知乎等,通过实地考察,灰度的技术无一例外都使用了以下CSS,如淘宝的:第一行对非IE浏览器生效,第二行是对IE浏览器生效(emmm…似乎浏览器就分为两种),本质上都是使用filter的grayscale属性,实现灰阶效果,灰阶是一种常用的图片滤镜。打开PS可以看到多种滤镜可选择:

今天(2020.04.04)很多网站都换成了灰色调,如淘宝百度掘金知乎等,通过实地考察,灰度的技术无一例外都使用了以下CSS,如淘宝的:

html {
    -webkit-filter: grayscale(100%);
    filter: progid:DXImageTransform.Microsoft.BasicImage(grayscale=1);
}

第一行对非IE浏览器生效,第二行是对IE浏览器生效(emmm…似乎浏览器就分为两种),本质上都是使用filter的grayscale属性,实现灰阶效果,灰阶是一种常用的图片滤镜。打开PS可以看到多种滤镜可选择:

CSS filter与前端滤镜

而通过CSS的filter能够实现其中的一些滤镜效果,如灰阶,高斯模糊等。

这个时候你可能会问,网页又不是图片,里面可能会有很多文本,为什么也能应用图片的滤镜呢?实际上网页在渲染到屏幕之前都会被栅格化成Canvas位图再画到屏幕上,所以filter处理的就是这张位图。

通过Chromium源码,我们可以看到相关滤镜的实现,实际上是使用了一个图像矩阵对原始位图进行转换,如下代码所示:

void GetGrayscaleMatrix(float amount, float matrix[20]) {
  // Note, these values are computed to ensure MatrixNeedsClamping is false
  // for amount in [0..1]
  matrix[0] = 0.2126f + 0.7874f * amount;
  matrix[1] = 0.7152f - 0.7152f * amount;
  matrix[2] = 1.f - (matrix[0] + matrix[1]);
  matrix[3] = matrix[4] = 0.f;
 
  matrix[5] = 0.2126f - 0.2126f * amount;
  matrix[6] = 0.7152f + 0.2848f * amount;
  matrix[7] = 1.f - (matrix[5] + matrix[6]);
  matrix[8] = matrix[9] = 0.f;
 
  matrix[10] = 0.2126f - 0.2126f * amount;
  matrix[11] = 0.7152f - 0.7152f * amount;
  matrix[12] = 1.f - (matrix[10] + matrix[11]);
  matrix[13] = matrix[14] = 0.f;
 
  matrix[15] = matrix[16] = matrix[17] = matrix[19] = 0.f;
  matrix[18] = 1.f;
}

这个便为灰阶grayscale的矩阵获取方式,如果CSS传的amount值为1(上面参数的便为1 – amount = 0,代码传参的时候使用了和1的差值),那么将得到以下矩阵:

CSS filter与前端滤镜

这个矩阵便是用来对每个像素点进行转换,假设某个像素点的像素值为rgba(255, 119, 50, 0.5),那么这个像素点转换计算如下:

CSS filter与前端滤镜

实际上对RGB每一位的计算为:

R/G/B = 255 * 0.2126 + 119 * 0.7152 + 50 * 0.0722 = 143

即使用公式:

这个其实就是灰阶算法,所谓灰阶例如黑白电视便是像素点只用一个维度表示:浅或深,所以需要把RGB三维数据处理成一维的,最简单的便是取RGB的平均值即可,但更科学的应该是用人眼对三原色的感知程度分配系数,这样能提高对比度。

那么为什么上面需要用一个矩阵计算呢,实际上统一成一个矩阵有一个显而易见好处是做多重变换的时候,只需要对这个矩阵进行累乘得到一个最终的矩阵即可,类似于transform. 例如可以在灰阶之后再加上棕褐色(sepia)的处理:

html {
  filter: grayscale(1) sepia(0.5);
}

如下图对比:

CSS filter与前端滤镜

棕褐色的矩阵获取方式为:

CSS filter与前端滤镜

如果灰阶的矩阵为A,棕褐色矩阵为B,那么此次的变换矩阵便为A * B(注意矩阵一般不满足交换律,A * B不等于B *A),如果我们先做棕褐色处理再做灰阶的话,最后的效果就是灰阶的。

我们发现 Direct2D 等引擎也是使用的这种方式进行变换,只不过采用的矩阵会有点差异:

CSS filter与前端滤镜

其它相对简单的滤镜如色调旋转(hue-rotate),反相(invert)等都是采用的这种矩阵变换,但是对于高斯模糊(blur)、投影(drop-shadow)等则是需要一些更复杂的算法,在源码里可以看到,高斯模糊是使用Skia的SkBlurImageFilter类做的处理,具体的计算过程可见 源码 。不管是矩阵还是单独的处理,它们都是继承于PaintFilter.

最后,本篇主要简单介绍了下filter滤镜的一些原理,通过采用一个图像变换矩阵做的处理,不同的滤镜变换的公式不一样,所采用的矩阵也不一样,多种效果可以通过矩阵累积成一个新的矩阵。同时,对于模糊和投影单独有一些更加高级的处理。

Post Views: 3


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

若为自由故

若为自由故

[美] Sam Williams / 邓楠、李凡希 / 人民邮电出版社 / 2015-4 / 49

理查德·马修·斯托曼(Richard Matthew Stallman,简称RMS)是自由软件之父,他是自由软件运动的精神领袖、GNU计划以及自由软件基金会的创立者。作为一个著名的黑客,他的主要成就包括Emacs及后来的GNU Emacs、GNU C 编译器及GDB 调试器。他编写的GNU通用公共许可证(GNU GPL)是世上最广为采用的自由软件许可证,为copyleft观念开拓出一条崭新的道路。......一起来看看 《若为自由故》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

MD5 加密
MD5 加密

MD5 加密工具