CSS filter与前端滤镜

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

内容简介:今天(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


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

查看所有标签

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

Fluent Python

Fluent Python

Luciano Ramalho / O'Reilly Media / 2015-8-20 / USD 39.99

Learn how to write idiomatic, effective Python code by leveraging its best features. Python's simplicity quickly lets you become productive with it, but this often means you aren’t using everything th......一起来看看 《Fluent Python》 这本书的介绍吧!

SHA 加密
SHA 加密

SHA 加密工具

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具