可以利用canvas获取绘制图片的每一个像素的信息,每一个像素信息由四个值表示:r g b a

滤镜例子

  • 这里需要一张 800*600 的图片如下所示:
    pic
  • 完整代码如下:
    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>

效果图如下:

pic
滤镜效果演示

保存图片

  • 最后可以通过 let str = c1.toDataURL();canvas 绘制的图片转为 base64 ,我们知道只要用到地址的地方都可以用 base64 比如 imgsrc
  • 注意:在 canvas 中所有的操作都是在上下文 gd 上的,除了这个 c1.toDataURL();