svg中的黑白(非灰度)滤镜,最好是snap.svg

Mic*_*ich 1 svg image-processing raphael svg-filters snap.svg

编辑1:重写问题,以便更清楚地理解.

这个真的让我分心.

我想对图像应用滤镜,使得超过某个阈值的值显示为完全白色,并且所有等于或小于阈值的值都是完全黑色的.

这是一张表示3x3像素图像的RGB值的地图:

|(255,255,255)|(220,220,220)|(100,100,100)|  
|(254,254,254)|(12 ,12 ,12 )|(38 ,38 ,38 )|  
|(201,201,201)|(105,105,105)|(60 ,60 ,60 )|
Run Code Online (Sandbox Code Playgroud)

应用我的过滤器后,我希望收到一个图像,其中所有大于200的值都转换为(255,255,255),所有等于或小于200的值都转换为(0,0,0),如:

|(255,255,255)|(255,255,255)|(0  ,0  ,0  )|
|(255,255,255)|(0  ,0  ,0  )|(0  ,0  ,0  )|
|(255,255,255)|(0  ,0  ,0  )|(0  ,0  ,0  )|
Run Code Online (Sandbox Code Playgroud)

我应该从哪里开始的想法?这在svg中甚至可能吗?我知道我可以在svg的过滤器中创建矩阵乘法,但我不知道如何处理这个问题.

谢谢!

编辑1: 我在数学交换中发布的相关问题:https: //math.stackexchange.com/questions/2087482/creating-binary-matrix-for-threshold-as-a-result-of-matrix-multiplcation

编辑2 ::从Snap.svg代码中提取:此矩阵将彩色图像转换为灰度:

<feColorMatrix type="matrix" values="0.2126 0.7152 0.0722 0 0 0.2126 0.7152 0.0722 0 0 0.2126 0.7152 0.0722 0 0 0 0 0 1 0"/>
Run Code Online (Sandbox Code Playgroud)

我想修改这里的值以获得黑色和白色,而不是获得灰度.我想选择高于哪个阈值返回白色的阈值,下面返回为黑色

附加信息:根据MSDN,这是乘法发生的方式:

Resulting vector   my coveted matrix     original vector
    | R' |     | a00 a01 a02 a03 a04 |   | R |
    | G' |     | a10 a11 a12 a13 a14 |   | G |
    | B' |  =  | a20 a21 a22 a23 a24 | * | B |
    | A' |     | a30 a31 a32 a33 a34 |   | A |
    | 1  |     |  0   0   0   0   1  |   | 1 |
Run Code Online (Sandbox Code Playgroud)

这又被应用于输入图像的每个像素.

Pau*_*eau 8

您可以使用<feComponentTransfer type="discrete">过滤器原语实现阈值处理.

这是一个例子.

<svg width="300" height="550" style="background-color: linen">
  <defs>
    <linearGradient id="gradient">
      <stop offset="0" stop-color="white"/>
      <stop offset="1" stop-color="black"/>
    </linearGradient>
    
    <filter id="threshold" color-interpolation-filters="sRGB">
      <feComponentTransfer>
        <feFuncR type="discrete" tableValues="0 1"/>
        <feFuncG type="discrete" tableValues="0 1"/>
        <feFuncB type="discrete" tableValues="0 1"/>
      </feComponentTransfer>
    </filter>
  </defs>

  <rect x="50" y="50" width="200" height="200" fill="url(#gradient)"/>
  <rect x="50" y="300" width="200" height="200" fill="url(#gradient)" filter="url(#threshold)"/>
</svg>
Run Code Online (Sandbox Code Playgroud)

这个原语是如何工作的,你为每个颜色组件创建一个带表.但是,波段的数量与输入有关,而与输出无关.想想它,因为输入被分成许多相同大小的频段.然后为每个波段分配输出值.因此,如果您希望拆分发生在50%(R,G或B = 0.5(128)),那么您创建两个波段,"0 1".第一个波段(0 - > 0.5)中的值被赋值为0,第二个波段(0.5 - > 1)中的值被赋值为1.

因此,例如,如果您想要达到20%(0.2或51)的阈值,则需要创建五个波段.输出表值为"0 1 1 1 1".

<svg width="300" height="550" style="background-color: linen">
  <defs>
    <linearGradient id="gradient">
      <stop offset="0" stop-color="white"/>
      <stop offset="1" stop-color="black"/>
    </linearGradient>
    
    <filter id="threshold" color-interpolation-filters="sRGB">
      <feComponentTransfer>
        <feFuncR type="discrete" tableValues="0 1 1 1 1"/>
        <feFuncG type="discrete" tableValues="0 1 1 1 1"/>
        <feFuncB type="discrete" tableValues="0 1 1 1 1"/>
      </feComponentTransfer>
    </filter>
  </defs>

  <rect x="50" y="50" width="200" height="200" fill="url(#gradient)"/>
  <rect x="50" y="300" width="200" height="200" fill="url(#gradient)" filter="url(#threshold)"/>
</svg>
Run Code Online (Sandbox Code Playgroud)

这种方法的缺点在于,它确实意味着如果要在任意组件值处进行阈值处理,则表中可能需要最多256个值.

为了演示这一点,在最后一个示例中,我使用一些javascript根据范围滑块设置的值更新过滤器表.

var selector = document.getElementById("selector");
var funcR = document.getElementById("funcR");
var funcG = document.getElementById("funcG");
var funcB = document.getElementById("funcB");

function updateFilter() {
  // Input value
  var threshold = selector.value;
  // Create the table
  var table = "0 ".repeat(threshold) + "1 ".repeat(256-threshold);
  // Update the filter components
  funcR.setAttribute("tableValues", table);
  funcG.setAttribute("tableValues", table);
  funcB.setAttribute("tableValues", table);
}

selector.addEventListener('input', updateFilter);

// Call the filter updater once at the start to initialise the filter table
updateFilter();
Run Code Online (Sandbox Code Playgroud)
<svg width="300" height="300" style="background-color: linen">
  <defs>
    <filter id="threshold" color-interpolation-filters="sRGB">
      <feComponentTransfer>
        <feFuncR id="funcR" type="discrete" tableValues="0 1 1 1"/>
        <feFuncG id="funcG" type="discrete" tableValues="0 1 1 1"/>
        <feFuncB id="funcB" type="discrete" tableValues="0 1 1 1"/>
      </feComponentTransfer>
    </filter>
  </defs>

  <image xlink:href="https://placekitten.com/g/300/300"
         x="50" y="50"width="200" height="200"
         filter="url(#threshold)"/>
</svg>

<form>
  <input id="selector" type="range" min="0" max="256"/>
</form>
Run Code Online (Sandbox Code Playgroud)

  • 情况似乎并非如此。我稍微修改了脚本以使其在 IE 中运行,并且在 IE11 中似乎可以正常工作。没试过Edge。https://jsfiddle.net/ga0xh0oj/ (2认同)