svg过滤器计算分辨率

时间:2018-04-20 07:18:08

标签: svg svg-filters

我正在对一系列图像应用svg滤镜,并且看起来滤镜在其计算中仅使用颜色的4个最高有效位,其余部分被忽略并且对结果没有影响。有没有办法强制过滤器在计算中包含所有8个颜色位。

为了说明我的问题,我创建了一个编译器,它构建了一组256个红色单元格,从0到256强度仅增加红色。 然后,我用一个线性标度对单元格进行过滤,将每个单元格颜色的位值乘以128.

我应该看到前两个三个单元格(位值0,1,2)为0,128和256强度为红色,其余应为256红色。

我看到十进制值小于8的所有内容都是0强度。

这表明在svg计算中忽略了前三位。为什么会这样。

https://codepen.io/jgbgy/pen/LmVGxG

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Threshold</title>
</head>
<body>
<div>
    <?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
    <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
    "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
    <svg xmlns="http://www.w3.org/2000/svg"
         xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve"
             width="1200" height="1024"
             viewBox="0 0 1200 1024" >

      <defs>

          <g id="colormap"></g>

          <!-- Filter Definition -->


         <filter id="linearred">
          <feComponentTransfer>
            <feFuncR type="linear" slope="128" intercept="0"/>
          </feComponentTransfer>
         </filter>


      </defs>
        <g>
            <use id="source" xlink:href="#colormap"/>
            <use y="200"  id= "redoption2" xlink:href="#colormap" filter="url(#linearred)" />
        </g>

    </svg>
</div>
<script>

        var svgns = "http://www.w3.org/2000/svg";
        var svg = document.getElementById("colormap");
        var cellSize = 10;
        var colCount = 16

                for (let r = 0; r < 256; r++) {
                    var cell = document.createElementNS(svgns, "rect");
                    var x = (r % colCount)
                    var y = Math.trunc(r/colCount)
                    cell.setAttributeNS(null, "x", x * cellSize);
                    cell.setAttributeNS(null, "y", y * cellSize);
                    cell.setAttributeNS(null, "width", cellSize);
                    cell.setAttributeNS(null, "height", cellSize);

                    RcolorHex = r.toString(16).padStart(2,"0");

                    hexColor = "#" + RcolorHex + "0000";
                    console.log(x, y, r, RcolorHex);
                    cell.setAttributeNS(null, "fill", hexColor);
                    svg.appendChild(cell);
                }

</script>
</body>
</html>

1 个答案:

答案 0 :(得分:2)

您的问题是由于过滤器为其操作使用不同的色彩空间。他们使用LinearRGB,而其他颜色操作,例如混合到屏幕,使用sRGB。

解决方案是将过滤器设置为使用sRGB。

color-interpolation-filters="sRGB"

<div>
    <?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
    <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
    "http://www.w3.org/Graphics/SVG/1.2/DTD/svg11.dtd">
    <svg xmlns="http://www.w3.org/2000/svg"
         xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve"
             width="1200" height="1024"
             viewBox="0 0 1200 1024" >

      <defs>

          <g id="colormap"></g>
          
          <!-- Filter Definition -->

         
         <filter id="linearred" color-interpolation-filters="sRGB">
          <feComponentTransfer>
            <feFuncR type="linear" slope="128" intercept="0"/>
          </feComponentTransfer>
         </filter>
          
          
      </defs>
        <g>
            <use id="source" xlink:href="#colormap"/>
            <use y="200"  id= "redoption2" xlink:href="#colormap" filter="url(#linearred)" />
        </g>

    </svg>
</div>
<script>

        var svgns = "http://www.w3.org/2000/svg";
        var svg = document.getElementById("colormap");
        var cellSize = 10;
        var colCount = 16

                for (let r = 0; r < 256; r++) {
                    var cell = document.createElementNS(svgns, "rect");
                    var x = (r % colCount)
                    var y = Math.trunc(r/colCount)
                    cell.setAttributeNS(null, "x", x * cellSize);
                    cell.setAttributeNS(null, "y", y * cellSize);
                    cell.setAttributeNS(null, "width", cellSize);
                    cell.setAttributeNS(null, "height", cellSize);

                    RcolorHex = r.toString(16).padStart(2,"0");

                    hexColor = "#" + RcolorHex + "0000";
                    //console.log(x, y, r, RcolorHex);
                    cell.setAttributeNS(null, "fill", hexColor);
                    svg.appendChild(cell);
                }

</script>

实际上IE / Edge实际上是错误的,而不是Chrome和Firefox:)