Как применить feBlend и сохранить исходную альфа - PullRequest
0 голосов
/ 21 мая 2018

Я пытаюсь изменить цвета изображения, применяя к нему feFlood и feBlend в режимах «светлее» и «темнее».Как сохранить альфа-канал?

<svg>
  <filter id="filter">
    <feFlood result="flood" flood-color="blue" />
    <feBlend in="SourceGraphic" in2="flood" mode="lighten" />
  </filter>
  <image filter="url(#filter)" href="https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png" />
</svg>

https://jsfiddle.net/utqghr0o/

Ответы [ 2 ]

0 голосов
/ 22 мая 2018

Я думаю, что ответ Павла близок, но не совсем корректен.

Формула feBlend:

Opacity of Final Pixel  = 1 - (1- Opacity of Image A Pixel)*(1- Opacity of Image B Pixel)

Если сначала сделать маску, а затем наложить, окончательная непрозрачность будетнемного прочьНапример, для пиксела с непрозрачностью 0,6 на изображении A конечная непрозрачность пикселя будет равна 1 - (.6 * .6) = .64

Это близко, но не так, как0.6.

Если вы хотите сохранить точную непрозрачность изображения А в конечном изображении - сначала нужно выполнить смешивание, а затем - маскирование.Это предполагает, что вы хотите, чтобы осветление было сделано на предварительно умноженных, "100% -прозрачно-эквивалентных" цветах, что обычно имеет место.

<svg width="544" height="184">
  <filter id="filter">
    <feFlood result="flood" flood-color="blue" />

    <feBlend in="SourceGraphic" in2="flood" mode="lighten" result="blend"/>
    <feComposite in="blend" in2="SourceAlpha" operator="atop" result="maskedflood"/>
  </filter>
  <image filter="url(#filter)" width="544" height="184" href="https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png" />
</svg>
0 голосов
/ 21 мая 2018

Способ осветления работает так, что он берет максимальное значение цвета из каждого канала каждого из двух входов (предварительно умноженное на альфа).Так что, если пиксель имеет нулевую непрозрачность, он никогда не будет считаться максимальным цветом для любого канала, и будет использоваться значение из другого входа.

Что вам нужно сделать, так это сначала замаскировать флуд с помощьюальфа из исходного изображения («SourceAlpha»), затем смешайте замаскированный поток с исходным изображением.

<svg width="544" height="184">
  <filter id="filter">
    <feFlood result="flood" flood-color="blue" />
    <feComposite in="flood" in2="SourceAlpha" operator="atop" result="maskedflood"/>
    <feBlend in="SourceGraphic" in2="maskedflood" mode="lighten" />
  </filter>
  <image filter="url(#filter)" width="544" height="184" href="https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png" />
</svg>
...