Эта четвертая статья серии об SVG-фильтрах, в которой Sara Soueidan покажет вам, как использовать feComponentTransfer для создания эффекта двухтонового фильтра.



Предлагаемая серия статей "Эффекты фильтрации SVG" Sara Soueidan, внештатного разработчика UI/UX интерфейса и автора многих технических статей, проживающей в Ливане, посвящена работе фильтров SVG и состоит из следующих статей:


Эффекты фильтрации SVG


  1. Эффекты фильтрации SVG. Часть 1. SVG фильтры 101
  2. Эффекты фильтрации SVG. Часть 2. Контурный текст при помощи feMorphology
  3. Эффекты фильтрации SVG. Часть 3. Эффект постеризации изображения при помощи feComponentTransfer
  4. Эффекты фильтрации SVG. Часть 4. Двухцветные изображения при помощи feComponentTransfer.


В предыдущей статье этой серии я познакомила вас с примитивом feComponentTransfer, и мы использовали его для ограничения количества цветов изображения, чтобы создать эффект постеризации. В этой статье мы рассмотрим, как этот примитив можно использовать для создания эффекта duotone, подобно Photoshop. Мы также научимся использовать его для управления интенсивностью и контрастностью цветов изображения.


Краткий Обзор


Немного повторим.


Примитив feComponentTransfer позволяет изменять каждый из компонентов R, G, B и A, присутствующих в пикселе. Другими словами, feComponentTransfer предоставляет независимое манипулирование каждого канала цвета, так же как и канала альфа, в элементе input.


Компоненты RGBA изменяются путем выполнения различных видов функций на этих компонентах. Для этого у каждого компонента есть собственный элемент. Эти компонентные элементы вложены в feComponentTransfer. Для RGBA это компонентные элементы feFuncR, feFuncG, feFuncB, и feFuncA.


Атрибут type используется в компонентном элементе для определения типа функции, которую требуется использовать для изменения этого компонента. В настоящее время доступно пять типов функций: identity, table, discrete, linear и gamma. Эти типы функций используются для изменения компонентов RGBA (цвета и альфа-канал) источника графики. Мы упомянули, что можно изменять один или несколько компонентов одновременно и что можно каналы изменять независимо, применяя различные функции к каждому компонентному элементу.


<feComponentTransfer>
    <!-- The RED component -->
    <feFuncR type="identity | table | discrete | linear | gamma"></feFuncR>

    <!-- The GREEN component -->
    <feFuncG type="identity | table | discrete | linear | gamma"></feFuncG>

    <!-- The BLUE component -->
    <feFuncB type="identity | table | discrete | linear | gamma"></feFuncB>

    <!-- The ALPHA component -->
    <feFuncA type="identity | table | discrete | linear | gamma"></feFuncA>
</feComponentTransfer>">

В предыдущей статье мы прояснили функцию discrete и увидели, как ее можно использовать для постеризации изображений. В этой статье мы начнем с использования функции table для создания эффекта duotone, аналогичного тому, что вы можете создать в Photoshop.


Создание двухцветного эффекта в Photoshop


Я не дизайнер и не разбираюсь в графических редакторах, таких как Photoshop. Когда я хотела создать двухцветный эффект в SVG, я сначала искала способ создать этот эффект в графическом редакторе, чтобы увидеть, могу ли я реплицировать его с помощью операций фильтрации, доступных в SVG. Как оказалось, шаги по созданию двухцветных изображений в SVG точно такие же, как и в Photoshop.


Следующее видео является ускоренной версией этого урока, который я нашла на YouTube.


В этом видео дизайнер создает двухцветный эффект, выполнив следующие действия:


  • Обесцветить изображение, сделав его оттенками серого.
  • Сопоставьте диапазон оттенков серого с новым диапазоном, который вместо черно-белого на обоих концах имеет два разных цвета, которые вы хотите использовать в двухцветном эффекте. Другими словами, необходимо создать и использовать карту градиента, с которой сопоставляются оттенки серого.

Давайте посмотрим, как эти шаги могут быть воспроизведены в SVG.


Создание двухцветного эффекта в SVG


Чтобы воссоздать этот эффект в SVG, нам нужно сначала обесцветить изображение. Это возможно выполнить с помощью примитива фильтра feColorMatrix.


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


Преобразование изображения в оттенки серого с помощью feColorMatrix


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


<svg viewBox="0 0 266 400">
    <filter id="duotone">

        <feColorMatrix type="matrix" values=".33 .33 .33 0 0
            .33 .33 .33 0 0
            .33 .33 .33 0 0
             0   0   0  1 0">
        </feColorMatrix>

        <!-- ... -->
    </filter>
    <image xlink:href="..." width="100%" x="0" y="0" height="100%" 
        filter="url(#duotone)"></image>
</svg>

На следующем рисунке изображение справа это результат применения вышеуказанного фильтра к изображению слева:


Результат (справа) преобразования изображения слева в оттенки серого с помощью операции фильтра feColorMatrix
Рис_1. Результат (справа) преобразования изображения слева в оттенки серого с помощью операции фильтра feColorMatrix.


Вы можете узнать все о feColorMatrix и как его использовать в этой статье Уна Кравец.


Теперь, когда наше изображение по существу состоит из серого градиента, нам нужно создать двухцветную карту градиента для отображения серого градиента.


Создание карты градиента с помощью функции переноса компонентов таблицы


В SVG для создания карты градиентов можно использовать примитив feComponentTransfer с таблицей типов.


В предыдущей статье мы видели, как можно сопоставить цвета изображения со списком цветов, предоставленным в атрибуте tableValues с помощью функции discrete. Браузер использует наш список tableValues для создания диапазонов, которые затем используются для сопоставления цветов со значениями, которые мы предоставили.


При использовании функции table мы также будем предоставлять значения цветов в атрибуте tableValues. Опять браузер будет использовать эти значения, чтобы сопоставить с ними цвета изображения. Однако отличается то, как браузер будет отображать эти цвета. Вместо сопоставления диапазонов цвета с дискретным значением цвета, он создаст цветовой диапазон из предоставленных значений, а затем сопоставит входной диапазон с этим новым диапазоном.


Предположим, мы хотим использовать два цвета для нашего двухтонального эффекта:


Исходные два цвета
Рис_2. Исходные два цвета.


Эти два цвета будут использоваться для создания градиентного отображения:


Градиент, созданный по двум значениям цвета
Рис_3. Градиент, созданный по двум значениям цвета.


… которому мы собираемся сопоставить нашу карту оттенков серого.


Отображение двухтональной карты двуцветному градиенту
Рис_4. Отображение двухтональной карты двуцветному градиенту.


Чтобы использовать эти цвета в feComponentTransfer, нам нужно получить значения каналов R, G и B каждого цвета. Поскольку tableValues содержит дробные значения, нам нужно преобразовать значения RGB в дроби. Значения цвета обычно находятся в диапазоне [0,255]. Чтобы преобразовать их в дроби, разделим их на 255.


Например, розовый цвет имеет следующие значения RGB:


R: 254
G: 32
B: 141

Преобразовав их в дробь, получим:


R: 254/255 = .996078431
G: 32/255  = .125490196
B: 141/255 = .552941176

Аналогично для значений желтого цвета получим:


R: .984313725
G: .941176471
B: .478431373

Теперь, когда у нас есть значения цветов, пришло время создать нашу карту градиента. Ранее мы упоминали, что когда мы предоставим значения tableValues для использования в функции table, браузер будет использовать tableValues для создания диапазона. Поэтому мы начнем с предоставления значений RGB двух цветов в качестве значений RGB для компонентных элементов:


<feComponentTransfer color-interpolation-filters="sRGB">
    <feFuncR type="table" tableValues=".996078431  .984313725"></feFuncR>
    <feFuncG type="table" tableValues=".125490196  .941176471"></feFuncG>
    <feFuncB type="table" tableValues=".552941176  .478431373"></feFuncB>
</feComponentTransfer>


В предыдущей статье мы видели, что при использовании функции discrete браузер создает n диапазонов для n значений в tableValues. Когда мы используем функцию table, браузер создает n-1 диапазон для n значений. Т.к. мы предоставили два tableValues для каждого компонента, это означает, что мы получим один диапазон ([розовый, желтый]) для каждого.


Теперь feComponentTransfer сделает свое дело: браузер будет просматривать последовательно каждый пиксель источника изображения. Для каждого пикселя он получит значение красного, зеленого и синего компонентов. Поскольку наше изображение имеет оттенки серого, значения R/G/B будут находиться в диапазоне [0, 1] = [черный, белый] (0 — полностью черный, 1 — полностью белый и оттенки серого между ними). Затем значение каждого компонента будет сопоставлено с новым диапазоном, указанным в tableValues.


Итак:


  • значение красного компонента будет сопоставлено диапазону [.996078431,.984313725];
  • синее значение компонента будет сопоставлено диапазону [.125490196,.941176471];
  • зеленое значение компонента будет сопоставлено диапазону [.552941176,.478431373].

Таким образом, к тому времени, когда браузер пройдет по всем пикселям изображения, вы замените все значения RGB в градиенте оттенков серого на значения RGB двухцветного градиентного отображения. В результате изображение станет двухцветным.


Результат (справа) отображения изображения с оттенками серого (слева) в нашу градиентную карту
Рис_6. Результат (справа) отображения изображения с оттенками серого (слева) в нашу градиентную карту.


Наш полный код теперь выглядит так:


<svg viewBox="0 0 266 400">
    <filter id="duotone">
        <!-- Grab the SourceGraphic (implicit) and convert it to grayscale -->
        <feColorMatrix type="matrix" values=".33 .33 .33 0 0
            .33 .33 .33 0 0
            .33 .33 .33 0 0
            0 0 0 1 0">
        </feColorMatrix>

        <!-- Map the grayscale result to the gradient map provided in tableValues -->
        <feComponentTransfer color-interpolation-filters="sRGB">
            <feFuncR type="table" tableValues=".996078431  .984313725"></feFuncR>
            <feFuncG type="table" tableValues=".125490196  .941176471"></feFuncG>
            <feFuncB type="table" tableValues=".552941176  .478431373"></feFuncB>
        </feComponentTransfer>
    </filter>

    <image xlink:href=".." width="100%" x="0" y="0" height="100%" 
       filter="url(#duotone)"></image>
</svg>

Вы можете поиграть с демо здесь:



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


Управление контрастностью и интенсивностью цвета с помощью функции переноса gamma


Используя компонентную функцию переноса gamma мы можем выполнить гамма-коррекцию нашего источника графики. Гамма-коррекция — это функция управления уровнями освещенности изображения.


Функция gamma имеет три атрибута, позволяющие управлять функцией гамма-коррекции, которые будут использоваться для управления освещенностью: амплитуда, экспонента и смещение. В совокупности они составляют следующую функцию переноса:


C' = amplitude * pow(C, exponent) + offset

gamma может использоваться для управления общей контрастностью изображения. Увеличение атрибута exponent делает темные области темнее, в то время как увеличение атрибута amplitude заставляет светлые области сиять больше. А это, в свою очередь, повышает общую контрастность изображения. Атрибут offset используется для увеличения интенсивности каждого компонента, а также влияет на полное изображение: как светлые, так и темные области.


Настройка контрастности как темных так и светлых областей изображения иногда может быть полезна, если вы не получили величины “блеска”, которое вы хотели бы видеть на изображении.


Например, если применить фильтр duotone из предыдущего раздела к следующему изображению, результат будет не таким “живым”, как хотелось бы:


Результат работы фильтра duotone
Рис_7. Результат работы фильтра duotone.


Двухцветное изображение справа выглядит немного бледным, а цвета слегка размытыми. Я хочу добавить контраста, чтобы оно выглядело более живым. Увеличим немного amplitude и exponent:


<feComponentTransfer color-interpolation-filters="sRGB">
    <feFuncR type="gamma" exponent="1.5" amplitude="1.3" offset="0"></feFuncR>
    <feFuncG type="gamma" exponent="1.5" amplitude="1.3" offset="0"></feFuncG>
    <feFuncB type="gamma" exponent="1.5" amplitude="1.3" offset="0"></feFuncB>
</feComponentTransfer>

Я смогла сделать светлые области более светящимися, а темные — более интенсивными:


Результат работы предыдущего кода
Рис_8. Результат работы гамма-коррекции.


Конечно, это только пример. Вы можете предпочесть более бледную версию изображения, особенно чтобы оно выглядело лучше с текстом сверху. Я думаю, что гамма-коррекция наиболее полезна для управления контрастностью черно-белых изображений. Если я применю ту же операцию гамма-коррекции к версии изображения в оттенках серого, то получу более благоприятную картину:


Результат работы гамма-коррекции для изображения в оттенках серого
Рис_9. Результат работы гамма-коррекции для изображения в оттенках серого.


Конечно же вы можете сделать противоположное и вместо увеличения контраста, можно немного осветлить темные области. В этом случае вы должны уменьшить значения атрибутов amplitude и/или exponent, а не увеличивать их. Значение по умолчанию для обоих равно 1. Значение по умолчанию атрибута offset равно 0.


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



SVG-инструмент Gradient Map


Yoksel уже некоторое время играет с SVG-фильтрами и недавно создал фантастический визуальный инструмент, позволяющий загружать изображение и применять различные двух и даже трехтональные эффекты, и который генерирует код фильтра SVG для вас, готовый для копирования и вставки в любое необходимое место. Это отличный инструмент для дальнейшего изучения feComponentTransfer.


Инструмент SVG-фильтра **Gradient Map** от Yoksel
Рис_10. Инструмент SVG-фильтра Gradient Map от Yoksel.


Инструмент даже позволяет настроить эффект оттенков серого, созданный с помощью feColorMatrix. В нашем коде мы использовали равное количество каналов R, G и B для получения эффекта оттенков серого. Это один из способов сделать изображение в оттенках серого. Но есть и другие способы. Например, можно создать эффект оттенков серого для каждого канала, что приведет к различным результатам оттенков серого для каждого канала:


Результат создания изображения в оттенках серого другими способами
Рис_11. Результат создания изображения в оттенках серого другими способами.


Я рекомендую немного поиграть с инструментом и проверить, как ваш выбор эффекта меняет базовый код, так как это один из лучших способов больше узнать о фильтрах SVG.


Заключение


Примитив feComponentTransfer дает нам большой контроль над цветовыми и альфа-компонентами изображений и позволяет создавать эффекты Photoshop-класса в комфорте наших редакторов кода.


В следующей статье этой серии мы рассмотрим еще несколько примитивов, которые позволяют нам воспроизвести еще один эффект Photoshop, используя почти те же шаги, что и в Photoshop, и еще раз покажем, как SVG может принести силу графических редакторов в веб-платформу. Мы узнаем, как смешать текст с цветом и текстурой фонового изображения, чтобы получить привлекательно выглядящие результаты. Оставайтесь с нами.

Комментарии (0)