web网站和图片如何黑白化

p-logo.png

愿凛冬消散,再无国殇。——2020.04.04

网站元素处理,CSS:filter

不卖关子,先上结果,CSS属性:

1
2
3
4
5
6
7
8
9
10
html {  
-webkit-filter: grayscale(100%);
-moz-filter: grayscale(100%);
-ms-filter: grayscale(100%);
-o-filter: grayscale(100%);
filter: grayscale(100%);
filter: url('url("data:image/svg+xml;utf8,<svg%20xmlns='http://www.w3.org/2000/svg'><filter%20id='grayscale'><feColorMatrix%20type='matrix'%20values='0.3333%200.3333%200.3333%200%200%200.3333%200.3333%200.3333%200%200%200.3333%200.3333%
200.3333%200%200%200%200%200%201%200'/></filter></svg>#grayscale");');
filter: gray;
}

1. filter

filter CSS属性将模糊或颜色偏移等图形效果应用于元素。滤镜通常用于调整图像,背景和边框的渲染。熟悉ps的同学会很喜欢这个属性。

IE:filter滤镜早先由IE支持,依稀记得当年用filter写opacity的IE6/7 hack代码。

IE6~9则可以直接通过filter实现元素黑白化:

1
2
3
html {
filter: gray;
}

但是IE10开始抛弃了filter滤镜,因此也导致IE新版至今无法用filter: grayscale()来实现网站的黑白效果。

w3c:CSS3中借鉴IE私有滤镜的方式提供了标准的CSS Filter方案

2.filter: grayscale(percent)

CSS3的Filter方案,将图像转换为灰度图像。值定义转换的比例。值为100%则完全转为灰度图像,值为0%图像无变化。值在0%到100%之间,则是效果的线性乘子。若未设置,值默认是0。

因此网站的黑白效果可以这么写:

1
2
3
4
5
6
7
html {  
-webkit-filter: grayscale(100%); /* webkit内核,Chrome,Safari */
-moz-filter: grayscale(100%); /* 虽然Firefox现在不支持,将来可能就支持了 */
-ms-filter: grayscale(100%); /* ie */
-o-filter: grayscale(100%); /* Opera */
filter: grayscale(100%); /* 标准写法 */
}

兼容性:

\[p-compatibility.png\]

  • 移动端iOS 9+,android5+;

  • PC Edge,Chrome,Safari,Opera支持。

效果前:

\[p-1_ori.png\]
效果后
\[p-1_gray.png\]

SVG effects for HTML

对于不兼容的IE和firefox,我们要实现黑白效果的话则可以通过SVG effects for HTML方式,即在 css样式中使用svg 来对HTML内容应用图像效果。

注意: 在外部文件引入的SVG必须与原始文件 同源

使用内嵌SVG

要想在CSS样式中应用SVG效果,首先需要创建一个引用SVG的CSS样式。

gray.svg

定义灰色滤镜,gray.svg:

1
2
3
4
5
<svg xmlns="http://www.w3.org/2000/svg">  
<filter id="grayscale">
<feColorMatrix type="matrix" values="0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0"/>
</filter>
</svg>

html中引用,并定义css

1
2
3
html {  
filter:url('gray.svg#grayscale'); /*灰度滤镜放在gray.svg文件的id叫做grayscale的滤镜里*/
}

内嵌gray.svg

如果该文件内嵌入了html文件里,则

1
2
3
html {  
filter: url('#grayscale');
}

直接css引用svg

1
2
3
4
html {    
filter: url('url("data:image/svg+xml;utf8,<svg%20xmlns='http://www.w3.org/2000/svg'><filter%20id='grayscale'><feColorMatrix%20type='matrix'%20values='0.3333%200.3333%200.3333%200%200%200.3333%200.3333%200.3333%200%200%200.3333%200.3333%
200.3333%200%200%200%200%200%201%200'/></filter></svg>#grayscale");')
}

兼容性:

\[p-svghtml-compatibility.png\]

如此则可以兼容除IE10/11外的绝大部分浏览器。

最后的兼容实现:

1
2
3
4
5
6
7
8
9
10
html {  
-webkit-filter: grayscale(100%);
-moz-filter: grayscale(100%);
-ms-filter: grayscale(100%);
-o-filter: grayscale(100%);
filter: grayscale(100%);
filter: url('url("data:image/svg+xml;utf8,<svg%20xmlns='http://www.w3.org/2000/svg'><filter%20id='grayscale'><feColorMatrix%20type='matrix'%20values='0.3333%200.3333%200.3333%200%200%200.3333%200.3333%200.3333%200%200%200.3333%200.3333%
200.3333%200%200%200%200%200%201%200'/></filter></svg>#grayscale");');
filter: gray;
}

图片处理

前端:canvas处理图片

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
/** 
* @function gray
* @param {DOMElement} imgObj
* @return {String}
*/
function gray(imgObj) {
let canvas = document.createElement('canvas'),
canvasContext = canvas.getContext('2d');

const imgW = imgObj.width,
imgH = imgObj.height;

canvas.width = imgW;
canvas.height = imgH;

canvasContext.drawImage(imgObj, 0, 0);

let imgPixels = canvasContext.getImageData(0, 0, imgW, imgH);

for (let y = 0; y < imgPixels.height; y++) {
for (let x = 0; x < imgPixels.width; x++) {
let i = (y * 4) * imgPixels.width + x * 4;
let avg = (imgPixels.data[i] + imgPixels.data[i + 1] + imgPixels.data[i + 2]) / 3;
imgPixels.data[i] = avg;
imgPixels.data[i + 1] = avg;
imgPixels.data[i + 2] = avg;
}
}
canvasContext.putImageData(imgPixels, 0, 0, 0, 0, imgPixels.width, imgPixels.height);
return canvas.toDataURL();
}

// use
let imgObj = document.getElementById('imgToGray'); // 要变灰的图片元素
imgObj.src = gray(imgObj);

服务端:ImageMagick和gm

有关ImageMagick和gm的更多使用说明可访问:【笔记】ImageMagick和gm

imagemagick命令

单张图片:

1
convert p-ori.jpg -colorspace Gray p-gray.jpg

p-gm.png

批量图片:

1
convert *.jpg -colorspace Gray p-gray.jpg

如当前目录含6张图片,上述命令会生成p-gray-0.jpg至p-gray-5.jpg。

Nodejs-gm模块

gm的colorspace方法。

单张图片:

1
2
3
4
5
6
7
8
const gm = require('gm').subClass({
imageMagick: true
});

gm("p-ori.png").colorspace('GRAY').write('./p-gray.png', function (err) {
if (err) console.error(err);
else console.log('success');
})

批量图片:

1
2
3
4
5
6
7
8
const gm = require('gm').subClass({
imageMagick: true
});

gm("*.png").colorspace('GRAY').write('./p-gray.png', function (err) {
if (err) console.error(err);
else console.log('success');
})

如当前目录含6张图片,上述命令会生成p-gray-0.png至p-gray-5.png。

定制化批量则通过遍历调用来实现。


相关链接