c语言编程笔录

首页 >   > 笔记大全

笔记大全

canvas学习和滤镜实现代码

更新时间:2023-10-01

前言

作为一名全栈程序员,Canvas是我们日常工作中的必备技能之一。Canvas是HTML5提供的一种新的图形绘制标签,它可以让我们在网页中绘制图像、动画等等,同时也为我们实现简单的图像处理提供了便利。 在本文中,我们将介绍Canvas的基本使用方法,以及如何利用Canvas实现常见的滤镜效果。

Canvas的基本使用方法

在HTML中,我们可以使用<canvas>标签来创建一个Canvas对象。需要注意的是,Canvas标签并不像标签那样拥有src属性,它是一个纯粹的图形绘制区域,我们需要使用JavaScript来绘制图形。

      <canvas id="myCanvas"></canvas>
    

在JavaScript中,我们可以使用Canvas的getContext()方法来获取Canvas的上下文对象,通过这个对象来控制图形的绘制操作。

      const canvas=document.getElementById('myCanvas');
      const ctx=canvas.getContext('2d');
    

我们可以使用Canvas上下文对象提供的方法来绘制图形。比如,下面的代码可以在Canvas上绘制一个蓝色的矩形。

      ctx.fillStyle='blue';
      ctx.fillRect(10, 10, 100, 100);
    

在Canvas中实现滤镜效果

在实现滤镜效果之前,我们需要了解Canvas上提供的常见的滤镜效果。

  • 灰度滤镜:将图像转换为灰度图像。
  • 反色滤镜:将图像的颜色取反。
  • 边缘检测滤镜:突出显示图像中的边缘。
  • 高斯模糊滤镜:模糊图像,产生柔和的效果。

接下来,我们将对这几种滤镜效果进行实现。

灰度滤镜

灰度滤镜是将图像元素的RGB值相加再平均,得到灰度值。使用下面的代码可以实现灰度滤镜。

      const img=new Image();
      img.onload=function() {
        ctx.drawImage(img, 0, 0);
        const imgData=ctx.getImageData(0, 0, canvas.width, canvas.height);
        const data=imgData.data;
        for (let i=0; i < data.length; i +=4) {
          const r=data[i];
          const g=data[i + 1];
          const b=data[i + 2];
          const gray=0.3 * r + 0.59 * g + 0.11 * b;
          data[i]=gray;
          data[i + 1]=gray;
          data[i + 2]=gray;
        }
        ctx.putImageData(imgData, 0, 0);
      };
      img.src='example.jpg';
    

反色滤镜

反色滤镜是将每个像素的RGB值按位取反。使用下面的代码可以实现反色滤镜。

      const img=new Image();
      img.onload=function() {
        ctx.drawImage(img, 0, 0);
        const imgData=ctx.getImageData(0, 0, canvas.width, canvas.height);
        const data=imgData.data;
        for (let i=0; i < data.length; i +=4) {
          data[i]=255 - data[i];
          data[i + 1]=255 - data[i + 1];
          data[i + 2]=255 - data[i + 2];
        }
        ctx.putImageData(imgData, 0, 0);
      };
      img.src='example.jpg';
    

边缘检测滤镜

边缘检测滤镜是通过差值来突出图片的边缘特征。使用下面的代码可以实现边缘检测滤镜。

      const img=new Image();
      img.onload=function() {
        ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
        const imgData=ctx.getImageData(1, 0, canvas.width - 1, canvas.height);
        
        const imgData2=ctx.getImageData(0, 0, canvas.width, canvas.height);
        const data=imgData.data;
        const data2=imgData2.data;

        for (let i=0, len=data.length; i < len; i +=4) {
          const r1=data2[(i - 4) < 0 ? i : (i - 4)];
          const g1=data2[(i - 3) < 0 ? i + 1 : (i - 3)];
          const b1=data2[(i - 2) < 0 ? i + 2 : (i - 2)];
          const gray1=(r1 + g1 + b1) / 3;

          const r2=data2[i];
          const g2=data2[i + 1];
          const b2=data2[i + 2];
          const gray2=(r2 + g2 + b2) / 3;

          const r3=data2[(i + 4) > len ? i : (i + 4)];
          const g3=data2[(i + 5) > len ? i + 1 : (i + 5)];
          const b3=data2[(i + 6) > len ? i + 2 : (i + 6)];
          const gray3=(r3 + g3 + b3) / 3;

          const d1=Math.abs(gray1 - gray3);
          const d2=Math.abs(gray1 - gray2);
          const d3=Math.abs(gray2 - gray3);
          const d=Math.max(d1, d2, d3);

          data[i]=data[i + 1]=data[i + 2]=d;
        }
        ctx.putImageData(imgData, 1, 0);
      };
      img.src='example.jpg';
    

高斯模糊滤镜

高斯模糊滤镜是一种特殊的模糊算法,它会在图像上产生柔和的效果。使用下面的代码可以实现高斯模糊滤镜。

      const img=new Image();
      img.onload=function() {
        ctx.drawImage(img, 0, 0);
        const imgData=ctx.getImageData(0, 0, canvas.width, canvas.height);

        const kernel=[[1, 2, 1], [2, 4, 2], [1, 2, 1]];
        const kernelSize=3;
        const kernelWeight=16;

        for (let x=0; x < imgData.width; x++) {
          for (let y=0; y < imgData.height; y++) {
            let r=0;
            let g=0;
            let b=0;
            for (let i=0; i < kernelSize; i++) {
              for (let j=0; j < kernelSize; j++) {
                const k=kernel[i][j];
                const index=(x + j - 1 + (y + i - 1) * imgData.width) * 4;
                r +=imgData.data[index] * k;
                g +=imgData.data[index + 1] * k;
                b +=imgData.data[index + 2] * k;
              }
            }
            const index=(x + y * imgData.width) * 4;
            imgData.data[index]=r / kernelWeight;
            imgData.data[index + 1]=g / kernelWeight;
            imgData.data[index + 2]=b / kernelWeight;
          }
        }
        ctx.putImageData(imgData, 0, 0);
      };
      img.src='example.jpg';
    

总结

Canvas是HTML5提供的一种新的图形绘制标签,它为我们实现图像处理提供了便利。在Canvas中实现滤镜效果,我们可以通过对像素点的操作来实现各种各样的效果,比如灰度滤镜、反色滤镜、边缘检测滤镜、高斯模糊滤镜等等。当然,我们在实现滤镜效果的时候要注意规避性能问题,比如可以使用Worker将图像处理操作放到一个单独的线程中执行。希望本文对大家在日常工作中使用Canvas有所帮助。