Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to invert alpha channel of svg

svg image

I have an SVG image like this. I would like to invert it, such that everything that is black becomes transparent, and everything that is transparent becomes black. So the result would be a black square with a transparent, square shaped 'hole' in the middle. How can I achieve this?

Code for the svg:

<svg
   xmlns="http://www.w3.org/2000/svg"
   viewBox="0 0 99.999997 99.999997"
   height="100"
   width="100">
  <g
     transform="translate(0,-952.36223)"
  >
    <path
       d="M 50.000001,954.80939 65.450848,986.11624 100,991.13652 74.999998,1015.5055 80.901699,1049.915 50,1033.6691 19.098298,1049.915 25.000001,1015.5055 -1.2134336e-6,991.13652 34.549151,986.11624 Z"
       style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:22.67716599;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
  </g>
</svg>

like image 533
rmacqueen Avatar asked Apr 08 '19 22:04

rmacqueen


People also ask

Is SVG transparent?

SVG supports animation, transparency, gradients, and is easily scalable without losing quality. PNG is a raster image format used for full-color images (mostly photos) in good quality. It has a rather high compression ratio and supports transparency.


2 Answers

Use the path as a mask like below:

body {
  background:pink;
}
<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg"
   viewBox="0 0 99.999997 99.999997">
  <defs>
    <mask id="hole">
      <rect width="100%" height="100%" fill="white"/>
      <path transform="translate(0,-952.36223)"
       d="M 50.000001,954.80939 65.450848,986.11624 100,991.13652 74.999998,1015.5055 80.901699,1049.915 50,1033.6691 19.098298,1049.915 25.000001,1015.5055 -1.2134336e-6,991.13652 34.549151,986.11624 Z"
       fill="black" />
    </mask>
  </defs>
  <rect fill="black" width="100%" height="100%" mask="url(#hole)" />
</svg>
like image 84
Temani Afif Avatar answered Sep 24 '22 18:09

Temani Afif


The original answer showed an approach using the feFuncA primitive - GetSelf pointed out below that it wasn't working due to browser bugs).

Another approach that works is to invert the alpha channel using a feColorMatrix filter. Updated code below. Note this still won't work on fully transparent colored shapes in Chrome since it seems to discard any color channel values for shapes with opacity below 0.005.

<svg
   xmlns="http://www.w3.org/2000/svg"
   viewBox="0 0 99.999997 99.999997"
   height="100"
   width="100">
  <defs>
    <filter id="invert-alpha">
      <feColorMatrix type="matrix" values="1 0 0 0 0 
                                       0 1 0 0 0 
                                       0 0 1 0 0
                                       0 0 0 -1 1"/>
</filter>
  </defs>
  <g
     transform="translate(0,-952.36223)" filter="url(#invert-alpha)"
  >
    <path
       d="M 50.000001,954.80939 65.450848,986.11624 100,991.13652 74.999998,1015.5055 80.901699,1049.915 50,1033.6691 19.098298,1049.915 25.000001,1015.5055 -1.2134336e-6,991.13652 34.549151,986.11624 Z"
       style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:22.67716599;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
  </g>
</svg>
like image 40
Michael Mullany Avatar answered Sep 23 '22 18:09

Michael Mullany