Canvas 图像滤镜 - 黑白
通过前几章节的学习,我们已经掌握了操作图像数据 ( ImageData ) 的大部分方法
我们知道可以通过 ImageData
对象的 data
属性获得由所有像素组成的一维数组
那么我们就可以操作这个数组实现各种滤镜,比如将彩照变成黑白照
图像滤镜 - 黑白
我们知道一个 RGB
演示值是由三个参数 ( R, G, B ) 一起构成的
- 如果
R = 255
,GB=0
那么就是红色 - 如果
G = 255
,RB=0
那么就是亮绿色 - 如果
B = 255
,RG=0
那么就是蓝色 - 如果全部为
0
那么就是 黑色 - 如果全部为
255
那么就是白色 - 如果三个取值都一样,那么就是灰色了
如果我们把所有的灰色系按从 #ffffff
到 #00000
连在一起,就会像下面这样
所以图像黑白滤镜的主要工作,就是把每个像素的 RGB
取一样的值?
那到底是哪个值呢? 一般的做法是取平均值,也就是说
R = G = B = (R+G+B)/2
业界最常用的做法是加权平均
R = G = B = 0.299R + 0.587G + 0.114B
知道了算法就好办了,我们可以使用一个 for
循环来重新设定 ImageData
for (var i = 0; i < data.length; i += 4) { var avg = (data[i] + data[i +1] + data[i +2]) / 3; data[i] = avg; // red data[i + 1] = avg; // green data[i + 2] = avg; // blue }
废话不多说,我们直接看范例
范例
我们将图片
黑白化
<!DOCTYPE html> <meta charset="utf-8"> <div style="border:1px solid #ccc"> <canvas id="canvas-1" width="520" height="300"> </canvas> </div> <script> var c = document.getElementById("canvas-1"); var ctx = c.getContext("2d"); var img = new Image(); img.src = '/static/i/meimei_160x160.png'; img.onload = function() { draw(this); }; function draw(img) { ctx.drawImage(img, 10, 10); img.style.display = 'none'; var imageData = ctx.getImageData(10,10,img.width, img.height); var imageData2 = ctx.getImageData(10,10,img.width, img.height); var data = imageData.data; for (var i = 0; i < data.length; i += 4) { var avg = (data[i] + data[i +1] + data[i +2]) / 3; data[i] = avg; // red data[i + 1] = avg; // green data[i + 2] = avg; // blue } ctx.putImageData(imageData, 20 + img.width, 10); var data2 = imageData2.data; for (var j = 0; j < data2.length; j += 4) { var avg2 = 0.299 * data2[j] + 0.587 * data2[j+1] + 0.114 * data2[j+2]; data2[j] = avg2; // red data2[j + 1] = avg2; // green data2[j + 2] = avg2; // blue } ctx.putImageData(imageData2, 30 + (img.width) * 2, 10); } </script>
运行结果如下