Search code examples
svgsvg-filters

svg filter to make translucent pixels opaque?


How would I create a svg filter to map all translucent pixels to opaque pixels? All transparent pixels should remain transparent.

I am trying to create a shape mask but need the edges of the masks to be fully opaque. Otherwise I am left with a halo when I use the mask. Here is an example of the halo I am trying to remove with this SVG filter: https://codepen.io/jedierikb/pen/yGYqKK

enter image description here

This answer here does something similar - setting all translucent pixels to transparent pixels using a feComponentTransfer.

Suggestions?


Solution

  • Here's one way. All values of A except for 0 are set to 1 (opaque).

    var ctx = canvas.getContext('2d');
    ctx.fillStyle = '#ABEDBE';
    ctx.fillRect(0,0,canvas.width,canvas.height);
    ctx.fillStyle = 'black';
    ctx.font = '14px sans-serif';
    ctx.textAlign = 'center';
    
    // first without filter
    ctx.fillText('no filter', 60, 20);
    drawArc();
    drawTriangle();
    // then with filter
    ctx.setTransform(1, 0, 0, 1, 120, 0);
    ctx.filter = 'url(#remove-alpha)';
    // and do the same ops
    ctx.fillText('no alpha', 60, 20);
    drawArc();
    drawTriangle();
    
    // to remove the filter
    ctx.filter = 'none';
    
    
    function drawArc() {
      ctx.beginPath();
      ctx.arc(60, 80, 50, 0, Math.PI * 2);
      ctx.stroke();
    }
    
    function drawTriangle() {
      ctx.beginPath();
      ctx.moveTo(60, 150);
      ctx.lineTo(110, 230);
      ctx.lineTo(10, 230);
      ctx.closePath();
      ctx.stroke();
    }
    // unrelated
    // simply to show a zoomed-in version
    var zCtx = zoomed.getContext('2d');
    zCtx.imageSmoothingEnabled = false;
    canvas.onmousemove = function drawToZoommed(e) {
      var x = e.pageX - this.offsetLeft,
        y = e.pageY - this.offsetTop,
        w = this.width,
        h = this.height;
        
      zCtx.clearRect(0,0,w,h);
      zCtx.drawImage(this, x-w/6,y-h/6,w, h, 0,0,w*3, h*3);
    }
    <svg width="0" height="0" style="position:absolute;z-index:-1;">
      <defs>
        <filter id="remove-alpha" x="0" y="0" width="100%" height="100%">
          <feComponentTransfer>
            <feFuncA type="discrete" tableValues="0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
                                                  1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
                                                  1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
                                                  1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
                                                  1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
                                                  1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
                                                  1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
                                                  1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
                                                  1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
                                                  1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
                                                  1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
                                                  1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
                                                  1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
                                                  1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
                                                  1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
                                                  1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1"></feFuncA>
          </feComponentTransfer>
          </filter>
      </defs>
    </svg>
    
    <canvas id="canvas" width="250" height="250" ></canvas>
    <canvas id="zoomed" width="250" height="250" ></canvas>