SVG feComponentTransfer для раскрашивания изображения - PullRequest
1 голос
/ 24 апреля 2019

Я пытаюсь раскрасить белое изображение с помощью фильтра, но получаю неожиданный результат

Образец SVG:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="373" height="400"
     viewBox="0 0 373 400">

    <defs>
        <filter id="colorize">
            <feComponentTransfer>
                <feFuncR type="linear" slope="0.3333333"></feFuncR>
                <feFuncG type="linear" slope="0"></feFuncG>
                <feFuncB type="linear" slope="0.3333333"></feFuncB>
            </feComponentTransfer>
        </filter>
    </defs>

    <g filter="url(#colorize)">
        <image x="0" y="0" xlink:href="https://i.imgur.com/Df8zD8O.png" width="373" height="400"></image>
    </g>
    <text font-weight="bold" fill="rgb(85,0,85)" x="0" y="100" font-size="100">Surfer</text>

</svg>

Ожидаемый результат: изображение становится того же цвета, что и текст
В этом случае #550055 или rgb(85,0,85)

Я установилнаклоны фильтра к 0.3333333 для R и B основаны на результате 85 / 255, но, как вы можете видеть, результат неправильный

Возможно, я использую неправильный методрасчет для достижения желаемого цвета

Следует отметить, что цвета с компонентами, приближающимися к 255 и равными ему, дают гораздо лучшие результаты

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="373" height="400"
     viewBox="0 0 373 400">

    <defs>
        <filter id="colorize">
            <feComponentTransfer>
                <feFuncR type="linear" slope="255"></feFuncR>
                <feFuncG type="linear" slope="0"></feFuncG>
                <feFuncB type="linear" slope="255"></feFuncB>
            </feComponentTransfer>
        </filter>
    </defs>

    <g filter="url(#colorize)">
        <image x="0" y="0" xlink:href="https://i.imgur.com/Df8zD8O.png" width="373" height="400"></image>
    </g>
    <text font-weight="bold" fill="rgb(255,0,255)" x="0" y="100" font-size="100">Surfer</text>

</svg>

Я основал свои вычисления на этой формуле

C' = slope * C + intercept

Что я делаю не так?

Ответы [ 2 ]

2 голосов
/ 25 апреля 2019

Цветовое пространство по умолчанию для большинства фильтров SVG - linearRGB . Вы, похоже, предполагаете, что это sRGB.

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="373" height="400"
     viewBox="0 0 373 400">

    <defs>
        <filter id="colorize" color-interpolation-filters="sRGB">
            <feComponentTransfer>
                <feFuncR type="linear" slope="0.3333333"></feFuncR>
                <feFuncG type="linear" slope="0"></feFuncG>
                <feFuncB type="linear" slope="0.3333333"></feFuncB>
            </feComponentTransfer>
        </filter>
    </defs>

    <g filter="url(#colorize)">
        <image x="0" y="0" xlink:href="https://i.imgur.com/Df8zD8O.png" width="373" height="400"></image>
    </g>
    <text font-weight="bold" fill="rgb(85,0,85)" x="0" y="100" font-size="100">Surfer</text>

</svg>
2 голосов
/ 25 апреля 2019

Вы должны установить цветовое пространство sRGB - потому что это цветовое пространство, которое использует свойство цвета CSS rgb ().(Цветовое пространство по умолчанию для фильтров SVG - linearRGB).

Добавьте color-interpolation-filters="sRGB" к фильтрующему элементу, и вы получите ожидаемый результат.

...