可以利用canvas获取绘制图片的每一个像素的信息,每一个像素信息由四个值表示:r g b a
滤镜例子
- 这里需要一张 800*600 的图片如下所示:
- 完整代码如下:
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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>canvas-像素级操作-滤镜</title>
<style>
body{background:#000;text-align: center;}
#canvas1{background-color: white;clear: both;}
#btn01,#btn02,#btn03,#btn003{width:100px;height:60px;background-color:mediumaquamarine;}
</style>
</head>
<body>
<input id="btn01" type="button" value="变灰" />
<input id="btn02" type="button" value="变黄" />
<input id="btn03" type="button" value="变绿" />
<input id="btn003" type="button" value="刷新页面" />
<div>
<canvas id="canvas1" width="800" height="600" >
您的浏览器不支持 canvas
</canvas>
</div>
<script>
window.onload = function() {
let c1 = document.getElementById("canvas1");
let gd = c1.getContext("2d");
let oImage = new Image();
oImage.src = '001.jpg';
oImage.onload = function() {
gd.drawImage(oImage,0,0);
let imageData = gd.getImageData(0,0,c1.width,c1.height);
//对于800*600的图片 有480000个像素 ,这里的length为 480000*4 = 1920000 这是因为要描述一个像素需要四个数 r g b a
// 第r行 第c列的像素位置可以表示为 (r*w+c)*4 w: 为图片像素的宽度这里是800 行列是从0 开始的
//第0 行 第 0 个像素:imageData.data[0]--imageData.data[3]
//第0 行 第 c 个像素:imageData.data[c*4]--imageData.data[c*4 + 3]
//第0 行 最后一 个像素:imageData.data[(w-1)*4]--imageData.data[(w-1)*4 + 3]
//第1 行 第 c 个像素:imageData.data[(w + c)*4]--imageData.data[(w + c)*4 + 3]
//第r 行 第 c 个像素:imageData.data[(r*w + c)*4]--imageData.data[(r*w + c)*4 + 3]
let btn01 = document.getElementById('btn01');
let btn02 = document.getElementById('btn02');
let btn03 = document.getElementById('btn03');
let btn003 = document.getElementById('btn003');
//变灰 的原理:取到 r g b 值相等就是灰 所以取r g b的平均值
btn01.onclick = function() {
for (var i=0;i<c1.width;i++) {
for (var j=0;j<c1.height;j++) {
let avg = (imageData.data[(j*c1.width+i)*4] + imageData.data[(j*c1.width+i)*4 + 1] + imageData.data[(j*c1.width+i)*4 + 2])/3;
imageData.data[(j*c1.width+i)*4] = imageData.data[(j*c1.width+i)*4 +1] = imageData.data[(j*c1.width+i)*4 + 2] = avg;
}
}
gd.putImageData(imageData,0,0);
};
//变黄 的原理:将rgb中的b去掉 剩下r和g合成就是黄
btn02.onclick = function() {
for (var i=0;i<c1.width;i++) {
for (var j=0;j<c1.height;j++) {
imageData.data[(j*c1.width+i)*4 + 2] = 0;
}
}
gd.putImageData(imageData,0,0);
};
//变绿 的原理:将rgb中的r和b去掉就行了
btn03.onclick = function() {
for (var i=0;i<c1.width;i++) {
for (var j=0;j<c1.height;j++) {
imageData.data[(j*c1.width+i)*4] = 0;
imageData.data[(j*c1.width+i)*4 + 2] = 0;
}
}
gd.putImageData(imageData,0,0);
};
//这种滤镜操作800*600 === 480000 循环很多次 不慢是因为在chrome 里面跑,用的v8引擎 用ie估计会卡死
btn003.onclick = function() {
location.href = 'test.html';
};
};
};
</script>
</body>
</html>
效果图如下:

滤镜效果演示
保存图片
- 最后可以通过
let str = c1.toDataURL();
将canvas
绘制的图片转为base64
,我们知道只要用到地址的地方都可以用base64
比如img
的src
等 - 注意:在
canvas
中所有的操作都是在上下文gd
上的,除了这个c1.toDataURL();