利用画布canvas,实现图片编辑马赛克效果。canvas.putImageData()实现不一样的马赛克

接到需求修改马赛克的样式,不知所措~,开始研究,实现效果如下图

在这里插入图片描述
重点都在代码注释中,就不多解释了

	drawImageToCanvas(image) {
      const canvas = document.querySelector('#canvas')
      const ctx = canvas.getContext('2d')
      return new Promise((resolve, reject) => {
        image.onload = function() {
          while (this.width > 1360 || this.height > 780) {
            this.width = this.width * 0.8 //图片的大小
            this.height = this.height * 0.8
          }
          canvas.width = this.width
          canvas.height = this.height
          ctx.drawImage(this, 0, 0, this.width, this.height)//宽高为图片尺寸,防止上传的图片大小使图片失真
          resolve(ctx)//返回画布对象信息
        }
      })
    },
	toEditImage() {//画布初始化
      this.editDialogVisible = true
      this.isEditImage = true
      const image = new Image()//创建图片信息
      image.crossOrigin = 'Annoymous'
      image.src = this.previewImgObj.fileUrl
      const that = this
      setTimeout(() => {//延迟开启画布
        that.drawImageToCanvas(image).then((ctx) => {//封装的方法,开启canvas
          canvas.onmousedown = function(ev){//通过鼠标事件来实现打码效果
            var quan = 9; //马赛克的大小
            var num = 3; //一次操作包含马赛克的个数
            var ev=ev || window.event;
            var dx = ev.layerX //鼠标中心位置
            var dy = ev.layerY //鼠标中心位置
            drawLine(image,dx,dy);
            document.onmousemove = function(ev){
              // console.log(canvas.offsetTop,canvas.offsetLeft,ev.layerX);
              var ev = ev || window.event;
              var mx = ev.layerX
              var my = ev.layerY
              if(Math.pow(dx-mx,2)+Math.pow(dy-my,2)>= Math.pow(quan*num,2)){  //(quan*马赛克个数*2)的平方
                drawLine(image,mx,my);
                dx = mx;
                dy = my;
              }
            };
            document.onmouseup = function(){
              that.dataURL = document.querySelector('#canvas').toDataURL('image/png')
              document.onmousemove = null;
              document.onmouseup = null;
            };
            function drawLine(obj,dx,dy){
              //原始图像
              var originalImgData = ctx.getImageData(0,0,canvas.width,canvas.height);
              var originalPxData = originalImgData.data;//获取图片像素信息
              for(var i=dx-quan*num;i<dx+quan*num;i = i+2*quan+1){//通过循环修改像素颜色
                  for(var j=dy-quan*num;j<dy+quan*num;j = j+2*quan+1){
                    //中心点(dx,dy)
                    if(!((i==dx-quan*num&&j==dy-quan*num)||(i==dx-quan*num&&j==dy-quan*num+2*quan+1)||
                      (i==dx-quan*num&&j==dy-quan*num+4*quan+2)||(i==dx-quan*num&&j==dy-quan*num+12*quan+6)||
                      (i==dx-quan*num&&j==dy-quan*num+14*quan+7)||(i==dx-quan*num&&j==dy-quan*num+16*quan+8)||
                      (i==dx-quan*num+16*quan+8&&j==dy-quan*num)||(i==dx-quan*num+16*quan+8&&j==dy-quan*num+2*quan+1)||
                      (i==dx-quan*num+16*quan+8&&j==dy-quan*num+4*quan+2)||(i==dx-quan*num+16*quan+8&&j==dy-quan*num+12*quan+6)||
                      (i==dx-quan*num+16*quan+8&&j==dy-quan*num+14*quan+7)||(i==dx-quan*num+16*quan+8&&j==dy-quan*num+16*quan+8)||
                      (i==dx-quan*num+2*quan+1&&j==dy-quan*num)||(i==dx-quan*num+4*quan+2&&j==dy-quan*num)||
                      (i==dx-quan*num+12*quan+6&&j==dy-quan*num)||(i==dx-quan*num+14*quan+7&&j==dy-quan*num)||
                      (i==dx-quan*num+2*quan+1&&j==dy-quan*num+16*quan+8)||(i==dx-quan*num+4*quan+2&&j==dy-quan*num+16*quan+8)||
                      (i==dx-quan*num+12*quan+6&&j==dy-quan*num+16*quan+8)||(i==dx-quan*num+14*quan+7&&j==dy-quan*num+16*quan+8))){

                      for(var x = -quan;x<=quan;x++){
                        for(var y = -quan;y<=quan;y++){
                          var xx = i+x;
                          var yy = j+y;
                          var pp = yy*canvas.width+xx; //周围的元素。
                          originalPxData[pp*4+0] = 255;//马赛克颜色
                          originalPxData[pp*4+1] = 255;
                          originalPxData[pp*4+2] = 255;
                        }
                      }
                    }
                  }
                }
                ctx.putImageData(originalImgData,0,0,0,0,canvas.width,canvas.height);//修改的信息放回画布
              }
            }
        })
      }, 20)
    },
    clearMasic() {//清除刚做的马赛克效果
      const canvas = document.querySelector('#canvas')
      const ctx = canvas.getContext('2d')
      const image = new Image()
      image.crossOrigin = 'Annoymous'
      image.src = this.previewImgObj.fileUrl
      image.onload = function() {
          ctx.drawImage(this, 0, 0, canvas.width, canvas.height)
      }
    },

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值