返回

Canvas滤镜让图片瞬间改变风格

前端

Canvas 凭借其强大的图形绘制能力,不仅可以绘制出各种图形、文本和位图,还能对位图进行复杂的像素运算和处理,从而实现各种各样的滤镜效果。

接下来,我们将见证 Canvas 实现滤镜效果的魅力。

首先,我们需要从 Canvas 中获取图片的像素数据。我们可以使用 Canvas 的 getImageData() 方法来实现。该方法返回一个包含图像像素数据的 ImageData 对象,其中包含每个像素的RGBA值。

var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
var imageData = context.getImageData(0, 0, canvas.width, canvas.height);

获取到像素数据后,就可以对图像进行各种滤镜操作了。

高斯模糊

高斯模糊是一种常用的图像模糊效果,可以使图像看起来更加柔和。

实现高斯模糊滤镜,可以使用以下公式:

newR = (r1 + r2 + r3 + r4 + r5 + r6 + r7 + r8 + r9) / 9;
newG = (g1 + g2 + g3 + g4 + g5 + g6 + g7 + g8 + g9) / 9;
newB = (b1 + b2 + b3 + b4 + b5 + b6 + b7 + b8 + b9) / 9;

其中,r1, g1, b1 是当前像素的 RGB 值,r2, g2, b2 是当前像素左侧像素的 RGB 值,r3, g3, b3 是当前像素右侧像素的 RGB 值,以此类推。

将该公式应用到每个像素上,即可得到高斯模糊后的图像。

for (var i = 1; i < imageData.width - 1; i++) {
  for (var j = 1; j < imageData.height - 1; j++) {
    var index = (j * imageData.width + i) * 4;

    var r1 = imageData.data[index - 4 * 1];
    var g1 = imageData.data[index - 4 * 1 + 1];
    var b1 = imageData.data[index - 4 * 1 + 2];

    var r2 = imageData.data[index - 4 * imageData.width];
    var g2 = imageData.data[index - 4 * imageData.width + 1];
    var b2 = imageData.data[index - 4 * imageData.width + 2];

    var r3 = imageData.data[index - 4 * imageData.width + 4];
    var g3 = imageData.data[index - 4 * imageData.width + 5];
    var b3 = imageData.data[index - 4 * imageData.width + 6];

    var r4 = imageData.data[index - 4];
    var g4 = imageData.data[index - 4 + 1];
    var b4 = imageData.data[index - 4 + 2];

    var r5 = imageData.data[index];
    var g5 = imageData.data[index + 1];
    var b5 = imageData.data[index + 2];

    var r6 = imageData.data[index + 4];
    var g6 = imageData.data[index + 4 + 1];
    var b6 = imageData.data[index + 4 + 2];

    var r7 = imageData.data[index + 4 * imageData.width];
    var g7 = imageData.data[index + 4 * imageData.width + 1];
    var b7 = imageData.data[index + 4 * imageData.width + 2];

    var r8 = imageData.data[index + 4 * imageData.width + 4];
    var g8 = imageData.data[index + 4 * imageData.width + 5];
    var b8 = imageData.data[index + 4 * imageData.width + 6];

    var r9 = imageData.data[index + 4 * 1];
    var g9 = imageData.data[index + 4 * 1 + 1];
    var b9 = imageData.data[index + 4 * 1 + 2];

    var newR = (r1 + r2 + r3 + r4 + r5 + r6 + r7 + r8 + r9) / 9;
    var newG = (g1 + g2 + g3 + g4 + g5 + g6 + g7 + g8 + g9) / 9;
    var newB = (b1 + b2 + b3 + b4 + b5 + b6 + b7 + b8 + b9) / 9;

    imageData.data[index] = newR;
    imageData.data[index + 1] = newG;
    imageData.data[index + 2] = newB;
  }
}

浮雕

浮雕是一种可以使图像看起来更有立体感和层次感的滤镜效果。

实现浮雕滤镜,可以使用以下公式:

newR = Math.abs(r1 - r2);
newG = Math.abs(g1 - g2);
newB = Math.abs(b1 - b2);

其中,r1, g1, b1 是当前像素的 RGB 值,r2, g2, b2 是当前像素左侧像素的 RGB 值。

将该公式应用到每个像素上,即可得到浮雕效果的图像。

for (var i = 1; i < imageData.width; i++) {
  for (var j = 1; j < imageData.height; j++) {
    var index = (j * imageData.width + i) * 4;

    var r1 = imageData.data[index];
    var g1 = imageData.data[index + 1];
    var b1 = imageData.data[index + 2];

    var r2 = imageData.data[index - 4];
    var g2 = imageData.data[index - 4 + 1];
    var b2 = imageData.data[index - 4 + 2];

    var newR = Math.abs(r1 - r2);
    var newG = Math.abs(g1 - g2);
    var newB = Math.abs(b1 - b2);

    imageData.data[index] = newR;
    imageData.data[index + 1] = newG;
    imageData.data[index + 2] = newB;
  }
}

锐化

锐化是一种可以使图像看起来更加清晰和锐利的滤镜效果。

实现锐化滤镜,可以使用以下公式:

newR = r1 - r2 + r3 + r4 - r5 + r6 + r7 - r8 + r9;
newG = g1 - g2 + g3 + g4 - g5 + g6 + g7 - g8 + g9;
newB = b1 - b2 + b3 + b4 - b5 + b6 + b7 - b8 + b9;

其中,r1, g1, b1 是当前像素的 RGB 值,r2, g2, b2 是当前像素左侧像素的 RGB 值,r3, g3, b3 是当前像素右侧像素的 RGB 值,以此类推。

将该公式应用到每个像素上,即可得到锐化效果的图像。

for (var i = 1; i < imageData.width - 1; i++) {
  for (var j = 1; j < imageData.height - 1; j++) {
    var index = (j * imageData.width + i) * 4;

    var r1 = imageData.data[index - 4 * 1];
    var g1 = imageData.data[index - 4 * 1 + 1];
    var b1 = imageData.data[index - 4 * 1 + 2];

    var r2 = imageData.data[index - 4 * imageData.width];
    var g2 = imageData.data[index - 4 * imageData.width + 1];
    var b2 = imageData.data[index - 4 * imageData.width + 2