愿凛冬消散,再无国殇。——2020.04.04
不卖关子,先上结果,CSS属性:
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,#grayscale");');
filter: gray;
}
filter
CSS属性将模糊或颜色偏移等图形效果应用于元素。滤镜通常用于调整图像,背景和边框的渲染。熟悉ps的同学会很喜欢这个属性。
IE:filter滤镜早先由IE支持,依稀记得当年用filter写opacity的IE6/7 hack代码。
IE6~9则可以直接通过filter实现元素黑白化:
html {
filter: gray;
}
但是IE10开始抛弃了filter滤镜,因此也导致IE新版至今无法用filter: grayscale()来实现网站的黑白效果。
w3c:CSS3中借鉴IE私有滤镜的方式提供了标准的CSS Filter方案
CSS3的Filter方案,将图像转换为灰度图像。值定义转换的比例。值为100%则完全转为灰度图像,值为0%图像无变化。值在0%到100%之间,则是效果的线性乘子。若未设置,值默认是0。
因此网站的黑白效果可以这么写:
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%); /* 标准写法 */
}
兼容性:
即
移动端iOS 9+,android5+;
PC Edge,Chrome,Safari,Opera支持。
效果前:
对于不兼容的IE和firefox,我们要实现黑白效果的话则可以通过SVG effects for HTML方式,即在 css样式中使用svg 来对HTML内容应用图像效果。
注意: 在外部文件引入的SVG必须与原始文件 同源
要想在CSS样式中应用SVG效果,首先需要创建一个引用SVG的CSS样式。
定义灰色滤镜,gray.svg:
<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
html {
filter:url('gray.svg#grayscale'); /*灰度滤镜放在gray.svg文件的id叫做grayscale的滤镜里*/
}
如果该文件内嵌入了html文件里,则
html {
filter: url('#grayscale');
}
html {
filter: url('url("data:image/svg+xml;utf8,#grayscale");')
}
兼容性:
如此则可以兼容除IE10/11外的绝大部分浏览器。
最后的兼容实现:
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,#grayscale");');
filter: gray;
}
/**
* @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
单张图片:
convert p-ori.jpg -colorspace Gray p-gray.jpg
批量图片:
convert *.jpg -colorspace Gray p-gray.jpg
如当前目录含6张图片,上述命令会生成p-gray-0.jpg至p-gray-5.jpg。
gm的colorspace方法。
单张图片:
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');
})
批量图片:
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。
定制化批量则通过遍历调用来实现。