Опубликован: 07.11.2007 | Доступ: свободный | Студентов: 1765 / 346 | Оценка: 4.29 / 4.14 | Длительность: 25:09:00
Специальности: Программист
Лекция 7:

Фильтры. Часть I

< Лекция 6 || Лекция 7: 123456 || Лекция 8 >

feBlend. feImage

Фильтр feBlend предназначен для получения режимов смешивания (наложения). Эта возможность входит почти во все графические пакеты.

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

Структура фильтра feBlend выглядит так (рис. 7.3):

Структура фильтра feBlend

увеличить изображение
Рис. 7.3. Структура фильтра feBlend

Для этого фильтра задается два атрибута входных изображений – in и in2. В значении первого подается фоновое изображение, например BackgroundImage. В значении второго подается верхнее изображение – SourceAlpha. Атрибут mode определяет режим смешивания, значения которого приводятся в табл. 7.4

Таблица 7.4. Атрибут "mode" фильтра feBlend
Значение Описание
normal Нормальный. Этот режим отображает верхний пиксель в обычном виде, независимо от цвета пикселей, находящихся под ним. Принят по умолчанию.
multiply Умножение. Берется значение цвета в каждом из каналов RGB и умножается значение верхнего цвета на значение нижнего цвета. Яркость результата получается всегда меньше яркости любого из отдельных слоев. Визуально режим напоминает просмотр двух наложенных друг на друга слайдов, направленных на светлый фон. Режим применяется для создания всяческих теней.
screen Осветление (экран). Режим противоположный Multiply. Берутся значения цвета в каждом из каналов RGB нижнего и верхнего слоев, инвертируется и перемножаются. Результат всегда получается более светлым. Визуально режим напоминает просмотр слайдов с помощью двух диаскопов, направленных на один экран (этим объясняется происхождение названия). Применяется для создания бликов и имитации свечения.
darken Замена темным. В каждом канале RGB верхнего и нижнего слоев сравниваются значения и выбираются более темные. Если слои верхнего пикселя темнее нижнего, они не изменяются. Если же они светлее, то заменяются на нижние. Этот режим применяется для подчеркивания изображения верхнего слоя с эффектом растворения в нижнем.
lighten Замена светлым. Режим, противоположный по своему действию режиму darken. В каждом канале RGB верхнего и нижнего слоев сравниваются значения и выбираются более светлые. Если слои верхнего пикселя светлее нижнего, они не изменяются. Если же они темнее, то заменяются на нижние. Этот режим также применяется для подчеркивания изображения верхнего слоя с эффектом растворения.

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

Таблица 7.5. Формулы вычисления режимов атрибута "mode"
Обозначения

cr = Цвет результирующего пикселя в канале RGB (Color Result)

qa = Значение прозрачности для данного пикселя изображения A

qb = Значение прозрачности для данного пикселя изображения B

ca = Цвет пикселя в канале RGB изображения A

cb = Цвет пикселя в канале RGB изображения B

Режим Формула для вычисления
normal cr = (1 - qa) * cb + ca
multiply cr = (1-qa)*cb + (1-qb)*ca + ca*cb
screen cr = cb + ca - ca * cb
darken cr = Min ((1 - qa) * cb + ca, (1 - qb) * ca + cb)
lighten cr = Max ((1 - qa) * cb + ca, (1 - qb) * ca + cb)

Фильтр feBlend поддерживает меньшее число режимов наложения, по сравнению с пакетом Adobe Photoshop (http://www.art-gu.ru/texts/files/db.0009/)

Для включения внешних изображений в определение filter нам придется познакомиться с еще одним очень простым фильтром feImage (рис. 7.4):

Структура фильтра feImage

Рис. 7.4. Структура фильтра feImage

Помимо стандартного набора x, y, width и height этот фильтр содержит единственный рабочий атрибут xlink:href, в котором указывается путь к изображению. Во всех последующих примерах растровое изображение располагается в той же самой папке, что и SVG – документ. Задача фильтра – включать внешнее изображение для обработки в составе filter.

В табл. 7.6 приводятся примеры использования фильтров feBlend и feImage.

Таблица 7.6. Фильтры feBlend и feImage.
Код Вид в браузере
7.6.1
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
 "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">

<svg width="200" height="500"
     xmlns="http://www.w3.org/2000/svg" version="1.1">
     <title> Лекция 7. Фильтры. Часть I </title>
     <desc>
          Пример feBlend1.svg
     </desc>

<rect x ="5" y="5" width="190" height="490" 
      stroke="blue" stroke-width="2" fill="none" ></rect>

<defs>
    <filter id="Normal">
      <feBlend mode="normal" in2="BackgroundImage" in="SourceGraphic"/>
    </filter>
    <filter id="Multiply">
      <feBlend mode="multiply" in2="BackgroundImage" in="SourceGraphic"/>
    </filter>
    <filter id="Screen">
      <feBlend mode="screen" in2="BackgroundImage" in="SourceGraphic"/>
    </filter>
    <filter id="Darken">
      <feBlend mode="darken" in2="BackgroundImage" in="SourceGraphic"/>
    </filter>
    <filter id="Lighten">
      <feBlend mode="lighten" in2="BackgroundImage" in="SourceGraphic"/>
    </filter>
</defs>

  <g enable-background="new" >
  <rect x="100" y="10" width="90" height="480"  fill="red"/>
      <rect x="20" y="20" width="160" height="50"  
            fill="blue"  filter="url(#Normal)" ></rect>
      <rect x="20" y="120" width="160" height="50"
            fill="blue" filter="url(#Multiply)" ></rect>
      <rect x="20" y="220" width="160" height="50"  
            fill="blue" filter="url(#Screen)" ></rect>
      <rect x="20" y="320" width="160" height="50"  
            fill="blue"  filter="url(#Darken)" ></rect>
      <rect x="20" y="420"  width="160" height="50"  
            fill="blue" filter="url(#Lighten)" ></rect>
  </g>
</svg>
Листинг 7.6.1. Пример feBlend1.svg
Описание
Попробуем вначале применить различные режимы смешивания для фигур, залитых однородным цветом. Мы видим, что результаты во 2 и 4, 3 и 5 случаях полностью сопадают.
Код Вид в браузере
7.6.2
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
 "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">

<svg width="200" height="500"
     xmlns="http://www.w3.org/2000/svg" version="1.1">
     <title> Лекция 7. Фильтры. Часть I </title>
     <desc>
          Пример feBlend2.svg
     </desc>

<rect x ="5" y="5" width="190" height="490" 
      stroke="blue" stroke-width="2" fill="none" ></rect>

<defs>
    <linearGradient id="MyGradient" >
      <stop offset="0" stop-color="#000000" />
      <stop offset=".33" stop-color="#ffffff" />
      <stop offset=".67" stop-color="#ff0000" />
      <stop offset="1" stop-color="#808080" />
    </linearGradient>
    <filter id="Normal">
      <feBlend mode="normal" in2="BackgroundImage" in="SourceGraphic"/>
    </filter>
    <filter id="Multiply">
      <feBlend mode="multiply" in2="BackgroundImage" in="SourceGraphic"/>
    </filter>
    <filter id="Screen">
      <feBlend mode="screen" in2="BackgroundImage" in="SourceGraphic"/>
    </filter>
    <filter id="Darken">
      <feBlend mode="darken" in2="BackgroundImage" in="SourceGraphic"/>
    </filter>
    <filter id="Lighten">
      <feBlend mode="lighten" in2="BackgroundImage" in="SourceGraphic"/>
    </filter>
</defs>

  <g enable-background="new" >
      <rect x="100" y="10" width="90" height="480"  
            fill="url(#MyGradient)"/>
      <rect x="20" y="20" width="160" height="50"  
            fill="blue"  filter="url(#Normal)" ></rect>
      <rect x="20" y="120" width="160" height="50"
            fill="blue" filter="url(#Multiply)" ></rect>
      <rect x="20" y="220" width="160" height="50"
            fill="blue" filter="url(#Screen)" ></rect>
      <rect x="20" y="320" width="160" height="50"
            fill="blue"  filter="url(#Darken)" ></rect>
      <rect x="20" y="420"  width="160" height="50"
            fill="blue" filter="url(#Lighten)" ></rect>
</g>
</svg>
Листинг 7.6.2. Пример feBlend2.svg
Описание
Теперь для фонового изображения применим градиентную заливку. Результаты получаются более интересными, но они опять-таки, частично совпадают.
Код Вид в браузере
7.6.3
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
 "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">

<svg width="200" height="500"
     xmlns="http://www.w3.org/2000/svg" version="1.1">
     <title> Лекция 7. Фильтры. Часть I </title>
     <desc>
          Пример feBlend3.svg
     </desc>

<rect x ="5" y="5" width="190" height="490" 
      stroke="blue" stroke-width="2" fill="none" ></rect>

<defs>
    <linearGradient id="MyGradient" >
      <stop offset="0" stop-color="#000000" />
      <stop offset=".33" stop-color="#ffffff" />
      <stop offset=".67" stop-color="#ff0000" />
      <stop offset="1" stop-color="#808080" />
    </linearGradient>
    
      <linearGradient id="MyGradient2" 
                      x1="0%" y1="0%" 
                      x2="0%" y2="100%"  >
      <stop offset="0" stop-color="#000000" />
      <stop offset=".33" stop-color="#ffffff" />
      <stop offset=".67" stop-color="#ff0000" />
      <stop offset="1" stop-color="#808080" />
    </linearGradient>
    
    <filter id="Normal">
      <feBlend mode="normal" in2="BackgroundImage" in="SourceGraphic"/>
    </filter>
    <filter id="Multiply">
      <feBlend mode="multiply" in2="BackgroundImage" in="SourceGraphic"/>
    </filter>
    <filter id="Screen">
      <feBlend mode="screen" in2="BackgroundImage" in="SourceGraphic"/>
    </filter>
    <filter id="Darken">
      <feBlend mode="darken" in2="BackgroundImage" in="SourceGraphic"/>
    </filter>
    <filter id="Lighten">
      <feBlend mode="lighten" in2="BackgroundImage" in="SourceGraphic"/>
    </filter>
</defs>

  <g enable-background="new" >
      <rect x="100" y="10" width="90" height="480"  
            fill="url(#MyGradient)"/>
      <rect x="20" y="20" width="160" height="50"  
            fill="url(#MyGradient2)"  filter="url(#Normal)" ></rect>
      <rect x="20" y="120" width="160" height="50"  
            fill="url(#MyGradient2)" filter="url(#Multiply)" ></rect>
      <rect x="20" y="220" width="160" height="50"  
            fill="url(#MyGradient2)" filter="url(#Screen)" ></rect>
      <rect x="20" y="320" width="160" height="50"  
            fill="url(#MyGradient2)"  filter="url(#Darken)" ></rect>
      <rect x="20" y="420"  width="160" height="50"  
            fill="url(#MyGradient2)" filter="url(#Lighten)" ></rect>
</g>
</svg>
Листинг 7.6.3. Пример feBlend3.svg
Описание
При использовании наложения фигур со схоже градиентной заливкой результаты проявляются более отчеливо. Теперь видно, что 2 и3, 4 и5 результаты диаметрально противоположны.
Код Вид в браузере
7.6.4
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
 "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">

<svg width="200" height="500"
     xmlns="http://www.w3.org/2000/svg" version="1.1">
     <title> Лекция 7. Фильтры. Часть I </title>
     <desc>
          Пример feBlend4.svg
     </desc>

<rect x ="5" y="5" width="190" height="490" 
      stroke="blue" stroke-width="2" fill="none" ></rect>

<defs>
    <linearGradient id="MyGradient" >
      <stop offset="0" stop-color="#000000" />
      <stop offset=".33" stop-color="#ffffff" />
      <stop offset=".67" stop-color="#ff0000" />
      <stop offset="1" stop-color="#808080" />
    </linearGradient>
    
        <linearGradient id="MyGradient2" x1="0%" y1="0%" 
                        x2="0%" y2="100%"  >
      <stop offset="0" stop-color="#000000" />
      <stop offset=".33" stop-color="#ffffff" />
      <stop offset=".67" stop-color="#ff0000" />
      <stop offset="1" stop-color="#808080" />
    </linearGradient>
    
    <filter id="Normal">
      <feBlend mode="normal" in2="BackgroundImage" in="SourceGraphic"/>
    </filter>
    <filter id="Multiply">
      <feBlend mode="multiply" in2="BackgroundImage" in="SourceGraphic"/>
    </filter>
    <filter id="Screen">
      <feBlend mode="screen" in2="BackgroundImage" in="SourceGraphic"/>
    </filter>
    <filter id="Darken">
      <feBlend mode="darken" in2="BackgroundImage" in="SourceGraphic"/>
    </filter>
    <filter id="Lighten">
      <feBlend mode="lighten" in2="BackgroundImage" in="SourceGraphic"/>
    </filter>
</defs>

  <g enable-background="new" >
      <rect x="10" y="10" width="180" height="480"  
            fill="url(#MyGradient)"/>
      <rect x="20" y="20" width="160" height="50"  
            fill="url(#MyGradient2)"  filter="url(#Normal)" ></rect>
      <rect x="20" y="120" width="160" height="50"  
            fill="url(#MyGradient2)" filter="url(#Multiply)" ></rect>
      <rect x="20" y="220" width="160" height="50"  
            fill="url(#MyGradient2)" filter="url(#Screen)" ></rect>
      <rect x="20" y="320" width="160" height="50"  
            fill="url(#MyGradient2)"  filter="url(#Darken)" ></rect>
      <rect x="20" y="420"  width="160" height="50"  
            fill="url(#MyGradient2)" filter="url(#Lighten)" ></rect>
</g>
</svg>
Листинг 7.6.4. Пример feBlend4.svg
Описание
Наложение фигур с градиентной заливкой. Результаты режимов хорошо видны.
Код Вид в браузере
7.6.5
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
 "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">

<svg width="200" height="500"
     xmlns="http://www.w3.org/2000/svg" version="1.1">
     <title> Лекция 7. Фильтры. Часть I </title>
     <desc>
          Пример feBlend5.svg
     </desc>

<rect x ="5" y="5" width="190" height="490" 
      stroke="blue" stroke-width="2" fill="none" ></rect>

<defs>
    <linearGradient id="MyGradient" >
      <stop offset="0" stop-color="#000000" />
      <stop offset=".33" stop-color="#ffffff" />
      <stop offset=".67" stop-color="#ff0000" />
      <stop offset="1" stop-color="#808080" />
    </linearGradient>
    
        <linearGradient id="MyGradient2" x1="0%" y1="0%" 
                        x2="0%" y2="100%"  >
      <stop offset="0" stop-color="#000000" />
      <stop offset=".33" stop-color="#ffffff" />
      <stop offset=".67" stop-color="#ff0000" />
      <stop offset="1" stop-color="#808080" />
    </linearGradient>
    
    <filter id="Normal">
      <feBlend mode="normal" in2="BackgroundImage" in="SourceGraphic"/>
    </filter>
    <filter id="Multiply">
      <feBlend mode="multiply" in2="BackgroundImage" in="SourceGraphic"/>
    </filter>
    <filter id="Screen">
      <feBlend mode="screen" in2="BackgroundImage" in="SourceGraphic"/>
    </filter>
    <filter id="Darken">
      <feBlend mode="darken" in2="BackgroundImage" in="SourceGraphic"/>
    </filter>
    <filter id="Lighten">
      <feBlend mode="lighten" in2="BackgroundImage" in="SourceGraphic"/>
    </filter>
</defs>

  <g enable-background="new" >
  <rect x="10" y="10" width="180" height="480"  
        fill="url(#MyGradient)"/>
          
      <g font-family="Verdana" font-size="42" fill="url(#MyGradient2)" >
      <text x="20" y="50" filter="url(#Normal)" >Normal</text>
      <text x="20" y="150" filter="url(#Multiply)" >Multiply</text>
      <text x="20" y="250" filter="url(#Screen)" >Screen</text>
      <text x="20" y="350" filter="url(#Darken)" >Darken</text>
      <text x="20" y="450" filter="url(#Lighten)" >Lighten</text>
    </g>
</g>
</svg>
Листинг 7.6.5. Пример feBlend5.svg
Описание
Наложение фигуры и текста со сходими градиентными заливками.
Код Описание
7.6.6
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
 "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">

<svg width="410" height="560"
     xmlns="http://www.w3.org/2000/svg" version="1.1">
     <title> Лекция 7. Фильтры. Часть I </title>
     <desc>
          Пример feBlendAndfeImage.svg
     </desc>
    
    <!--Вставка исходных изображений -->   
    <image id= "myImageInsert" x="20" y="20" 
           width="185" height="125" xlink:href="sea1.jpg"/> 
    <image id= "myImage2Insert" x="205" y="20" 
           width="185" height="125" xlink:href="sea2.jpg"/>  

    <defs>
    <!--Применение фильтра к изображению "sea1.jpg" с режимом "normal"-->
    <filter id="Normal" filterUnits="userSpaceOnUse"
      x="20" y="170" width="185" height="125">
      <feImage xlink:href="sea1.jpg" result="myImage1"/>
      <feImage xlink:href="sea2.jpg" result="myImage2"/>
      <feBlend in="myImage1" in2="myImage2" mode="normal"/>
    </filter>

    <!--Применение фильтра к изображению "sea2.jpg" с режимом "normal"-->
    <filter id="Normal2" filterUnits="userSpaceOnUse"
      x="205" y="170" width="185" height="125">
      <feImage xlink:href="sea1.jpg" result="myImage1"/>
      <feImage xlink:href="sea2.jpg" result="myImage2"/>
      <feBlend in="myImage2" in2="myImage1" mode="normal"/>
    </filter>    
    
    <!--Применение фильтров к изображению "sea1.jpg" с различными режимами-->
     <filter id="Multiply" filterUnits="userSpaceOnUse"
      x="20" y="295" width="185" height="125">
      <feImage xlink:href="sea1.jpg" result="myImage1"/>
      <feImage xlink:href="sea2.jpg" result="myImage2"/>
      <feBlend in="myImage1" in2="myImage2" mode="multiply"/>
    </filter>
    
      <filter id="Screen" filterUnits="userSpaceOnUse"
      x="205" y="295" width="185" height="125">
      <feImage xlink:href="sea1.jpg" result="myImage1"/>
      <feImage xlink:href="sea2.jpg" result="myImage2"/>
      <feBlend in="myImage1" in2="myImage2" mode="screen"/>
    </filter>
  
    <filter id="Darken" filterUnits="userSpaceOnUse"
      x="20" y="420" width="185" height="125">
      <feImage xlink:href="sea1.jpg" result="myImage1"/>
      <feImage xlink:href="sea2.jpg" result="myImage2"/>
      <feBlend in="myImage1" in2="myImage2" mode="darken"/>
    </filter>
      
    <filter id="Lighten" filterUnits="userSpaceOnUse"
      x="205" y="420" width="185" height="125">
      <feImage xlink:href="sea1.jpg" result="myImage1"/>
      <feImage xlink:href="sea2.jpg" result="myImage2"/>
      <feBlend in="myImage1" in2="myImage2" mode="lighten"/>
    </filter>

</defs>
    <!--Рисование прямоугольников, с применением к ним фильтров-->
    <rect x="20" y="170" width="185" height="125" 
          style="filter: url(#Normal)"/>
    <rect x="205" y="170" width="185" height="125" 
          style="filter: url(#Normal2)"/>
    <rect x="20" y="295" width="185" height="125" 
          style="filter: url(#Multiply)"/>
    <rect x="205" y="295" width="185" height="125"  
          style="filter: url(#Screen)"/>
    <rect x="20" y="420" width="185" height="125"  
          style="filter: url(#Darken)"/>
    <rect x="205" y="420" width="185" height="125"  
          style="filter: url(#Lighten)"/>
           
   <!--Вспомогательные фигуры-->
   <!--Первый контурный прямоугольник-->
    <rect x ="15" y="15" width="380" height="135"  
           stroke="blue" stroke-width="2" fill="none" ></rect>
    <!--Второй контурный прямоугольник-->
    <rect x ="15" y="165" width="380" height="385"  
          stroke="blue" stroke-width="2" fill="none" ></rect>
    
    <!--Подписи-->
      <text x="30" y="35"   style="fill: red; font-size: 16px">
            sea1.jpg</text>
      <text x="215" y="35"  style="fill: red; font-size: 16px">
            sea2.jpg</text>
      <text x="30" y="185"  style="fill: red; font-size: 16px">
            normal</text>
      <text x="215" y="185" style="fill: red; font-size: 16px">  
            normal</text>
      <text x="30" y="310" style="fill: red; font-size: 16px">  
            multiply</text>
      <text x="215" y="310" style="fill: red; font-size: 16px">
            screen</text>
      <text x="30" y="435" style="fill: red; font-size: 16px">
            darken</text>
      <text x="215" y="435" style="fill: red; font-size: 16px">
            lighten</text>
</svg>
Листинг 7.6.6. Пример feBlendAndfeImage.svg
Все рассмотренные выше примеры не позволяли отчетливо представить себе действие различных режимов. На практике, хорошие результаты можно получать смешивая два (или более) растровых изображения. В этом примере получается достаточно интересный коллаж для режимов screen и lighten.
Вид в браузере

Результат применения фильтра feBlend в значительной мере зависит от составляющих изображений. Попробуйте самостоятельно подобрать различные фотографии для наиболее четкого выражения режимов.

< Лекция 6 || Лекция 7: 123456 || Лекция 8 >