Я пытаюсь понять, как применяется непрозрачность 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
я не нашел точки, где это происходит ...