1

I have an icon in an external svg file which I can not edit. It is black and white.

I am including this external SVG in my own SVG via

<image x="1mm" y="1mm" width="7mm" height="7mm" xlink:href="myExternal.svg" />

Now I need to invert the "colors" of the external SVG (i.e., make white black and black white). My assumption was, that this certainly must be possible using pure SVG. I tried:

  • filter: invert(100%);
  • Setting the external SVG up as a mask for a rect with fill color in different combinations

Any ideas?

ThE_-_BliZZarD
  • 722
  • 2
  • 12
  • 26

1 Answers1

1

CSS filters can be expressed in terms of SVG filters; here is a list.

The one thing you need to consider in addition is that if you have a simple icon file defining a path (that by default is filled black), the default background is transparent black. So a filter that works on the RGB channels sees no contrast between the path and its background.

(For the following examples I've inserted the image as a data uri instead of an external image.)

The simple solution for this sort of icon would be to invert the opacity:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200">
  <defs id="defs6">
    <filter filterUnits="objectBoundingBox" id="invert" x="0" y="0" height="1" width="1">
      <feComponentTransfer>
          <feFuncA type="table" tableValues="1 0"/>
      </feComponentTransfer>
    </filter>
  </defs>
  <image filter="url(#invert)" xlink:href='data:image/svg+xml,%3c?xml version="1.0" encoding="UTF-8" standalone="no"?>%3csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">%3cpath d="M 425.403,330.939 C 408.414,314.154 390.857,296.796 390.857,214.856 390.857,131.83 329.899,62.782 250.39,50.094 A 31.843,31.843 0 0 0 256,32 C 256,14.327 241.673,0 224,0 206.327,0 192,14.327 192,32 A 31.848,31.848 0 0 0 197.609,50.095 C 118.101,62.783 57.143,131.831 57.143,214.857 57.143,296.79 39.592,314.149 22.6,330.935 -25.496,378.441 9.726,448 66.919,448 H 160 C 160,483.346 188.654,512 224,512 259.346,512 288,483.346 288,448 H 381.08 C 438.27,448 473.495,378.417 425.403,330.939 Z M 224,472 C 210.766,472 200,461.234 200,448 H 248 C 248,461.234 237.234,472 224,472 Z M 381.092,400 H 66.9 C 50.138,400 41.765,379.61 53.566,367.809 82.151,339.224 105.143,312.085 105.143,214.857 105.143,149.319 158.462,96 224,96 289.538,96 342.857,149.319 342.857,214.857 342.857,312.507 366.078,339.431 394.425,367.809 406.278,379.661 397.783,400 381.092,400 Z" />%3c/svg>' y="50" x="50" height="100" width="100" />
</svg>

For a more complete solution, you would place a white flood-filling behind the image and then invert all colors:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200">
  <defs id="defs6">
    <filter filterUnits="objectBoundingBox" id="invert" x="0" y="0" height="1" width="1">
      <feFlood flood-color="rgb(255,255,255)" result="background" />
      <feBlend mode="normal" in="SourceGraphic" in2="background" />
      <feComponentTransfer>
          <feFuncR type="table" tableValues="1 0"/>
          <feFuncG type="table" tableValues="1 0"/>
          <feFuncB type="table" tableValues="1 0"/>
      </feComponentTransfer>
    </filter>
  </defs>
  <image filter="url(#invert)" xlink:href='data:image/svg+xml,%3c?xml version="1.0" encoding="UTF-8" standalone="no"?>%3csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">%3cpath d="M 425.403,330.939 C 408.414,314.154 390.857,296.796 390.857,214.856 390.857,131.83 329.899,62.782 250.39,50.094 A 31.843,31.843 0 0 0 256,32 C 256,14.327 241.673,0 224,0 206.327,0 192,14.327 192,32 A 31.848,31.848 0 0 0 197.609,50.095 C 118.101,62.783 57.143,131.831 57.143,214.857 57.143,296.79 39.592,314.149 22.6,330.935 -25.496,378.441 9.726,448 66.919,448 H 160 C 160,483.346 188.654,512 224,512 259.346,512 288,483.346 288,448 H 381.08 C 438.27,448 473.495,378.417 425.403,330.939 Z M 224,472 C 210.766,472 200,461.234 200,448 H 248 C 248,461.234 237.234,472 224,472 Z M 381.092,400 H 66.9 C 50.138,400 41.765,379.61 53.566,367.809 82.151,339.224 105.143,312.085 105.143,214.857 105.143,149.319 158.462,96 224,96 289.538,96 342.857,149.319 342.857,214.857 342.857,312.507 366.078,339.431 394.425,367.809 406.278,379.661 397.783,400 381.092,400 Z" />%3c/svg>' y="50" x="50" height="100" width="100" />
</svg>
ccprog
  • 20,308
  • 4
  • 27
  • 44
  • "The one thing you need to consider in addition is that if you have a simple icon file defining a path (that by default is filled black), the default background is transparent black." Do you have any sources/reference materials on this? – Blake Gearin Jul 25 '22 at 04:11
  • [transparent](https://www.w3.org/TR/css-color-3/#transparent) is defined as `rgba(0, 0, 0, 0)`. – ccprog Jul 25 '22 at 13:23