Почему непрозрачность svg меняет значения RGB

Я пытаюсь понять, как применяется непрозрачность svg, чтобы я мог добавить прозрачность, а затем удалить ее и получить исходное изображение.

Я разработал следующий тестовый пример, в котором 256 ячеек увеличивают интенсивность красного.

У оригинала непрозрачность Затем я добавляю непрозрачность с помощью скрипта непосредственно в каждую ячейку svg. Затем я использую фильтр, чтобы удалить непрозрачность, удалив альфа-канал.

Это третье изображение должно совпадать с первым. Это не так. Когда вы смотрите на 1-й и 3-й прямоугольники, очевидно, что изображение с удаленным альфа-каналом потеряно в разрешении.

Это происходит в Chrome и Edge, как показано на рисунке ниже.

Цвет ячейки изменился в результате добавления прозрачности

Возможно ли иметь произвольный альфа-канал, который можно добавить к изображению и удалить с помощью фильтра без изменения исходного изображения?

        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);
                    
                    let Alpha = (r+1)/256


                    let hexColor = "#" + r.toString(16).padStart(2,"0") + "0000";
                    cell.setAttributeNS(null, "fill-opacity", Alpha);
                    cell.setAttributeNS(null, "fill", hexColor);
                    
                    svg.appendChild(cell);
                }

                var svg = document.getElementById("colormapNoAlpha");
                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);
                    
                    hexColor = "#" + r.toString(16).padStart(2,"0") + "0000";

                    cell.setAttributeNS(null, "fill", hexColor);
                    cell.setAttributeNS(null, "fill-opacity", 1);
                    svg.appendChild(cell);
                }
<html lang = "en">
<head>
    <meta charset = "UTF-8">
    <title>Alpha Layers</title>
</head>
<body>
  
<div>
    <svg xmlns = "http://www.w3.org/2000/svg"
         xmlns:xlink = "http://www.w3.org/1999/xlink" xml:space = "preserve"
             width = "880" height = "240"
             viewBox = "0 0 880 240" >
      <defs>
            <!-- Pattern Definition -->
            <pattern id = "checkerPattern" patternUnits = "userSpaceOnUse"
                    x = "0" y = "0" width = "20" height = "20"
                    viewBox = "0 0 10 10" >
                <line x1 = "0" y1 = "0" x2 = "10" y2 = "0" stroke = "lightblue" fill = "none" stroke-dasharray = "2,2" />
                <line x1 = "0" y1 = "0" x2 = "0" y2 = "10" stroke = "lightblue" fill = "none" stroke-dasharray = "2,2" />
                <rect x1 = "0" y1 = "0" width = "20" height = "20" stroke = "lightblue" fill = "black" stroke-dasharray = "2,2" />
            </pattern>
          <!-- Filter Definition -->
        <g id = "colormapNoAlpha"></g>  
        <g id = "colormap"></g>
          <filter id = "original" color-interpolation-filters = "sRGB">
            <feColorMatrix in = "SourceGraphic" result = "img2"
                type = "matrix"
                values = "1   0   0   0   0
                        0   1   0   0   0
                        0   0   1   0   0
                        0   0   0   1   0 "/>
          </filter>
        
          <filter id = "removeAlpha" color-interpolation-filters = "sRGB">
            <feColorMatrix in = "SourceGraphic" result = "img2"
                type = "matrix"
                values = "1   0   0   0   0
                        0   1   0   0   0
                        0   0   1   0   0
                        0   0   0   0   1 "/>
          </filter>
          <filter id = "selectAlpha" color-interpolation-filters = "sRGB">
            <feColorMatrix in = "SourceGraphic" result = "img2"
                type = "matrix"
                values = "0   0   0   1   0
                        0   0   0   1   0
                        0   0   0   1   0
                        0   0   0   0   1 "/>
          </filter>
        
          
      </defs>
      
      <!-- Background -->
	    <rect x = "0" y = "0" width = "100%" height = "100%" fill = "url(#checkerPattern)" />
	    <!-- Result -->
        <g>
          
          <use x = "020" y = "020" id = "in" xlink:href = "#colormapNoAlpha"/>
          <use x = "220" y = "020" id = "in" xlink:href = "#colormap"/>
            
          <!-- filter = "url(#removeAlpha)"   -->
          <use x = "420" y = "020" id = "out1" xlink:href = "#colormap" filter = "url(#removeAlpha)" />
            
          <use x = "640" y = "020" id = "out1" xlink:href = "#colormap" filter = "url(#selectAlpha)" />
          <text x = "020" y = "220" font-family = "Verdana" font-size = "20" fill = "white">Original</text>
          <text x = "220" y = "220" font-family = "Verdana" font-size = "20" fill = "white">Original Alpha</text>
          <text x = "420" y = "220" font-family = "Verdana" font-size = "20" fill = "white">Remove Alpha</text>
          <text x = "640" y = "220" font-family = "Verdana" font-size = "20" fill = "white">Only Alpha</text>
        </g>
    </svg>
</div>

</body>
</html>

Могу подтвердить ваш результат для Firefox / Linux. Это явно проблема с округлением значений в результате преобразования между цветовым пространством sRGB и linearRGB. Это происходит для двух операций: вычисления значений фильтра и альфа-компоновки цветов в их фон. Проблема в том, что даже после трех часов игры с атрибутами color-interpolation и color-interpolation-filters я не нашел точки, где это происходит ...

ccprog 02.05.2018 20:47
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Введение в CSS
Введение в CSS
CSS является неотъемлемой частью трех основных составляющих front-end веб-разработки.
Как выровнять Div по центру?
Как выровнять Div по центру?
Чтобы выровнять элемент <div>по горизонтали и вертикали с помощью CSS, можно использовать комбинацию свойств и значений CSS. Вот несколько методов,...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
Toor - Ангулярный шаблон для бронирования путешествий
Toor - Ангулярный шаблон для бронирования путешествий
Toor - Travel Booking Angular Template один из лучших Travel & Tour booking template in the world. 30+ валидированных HTML5 страниц, которые помогут...
2
1
65
0

Другие вопросы по теме