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

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

< Лекция 8 || Лекция 9: 12345 || Лекция 10 >

Рассмотрим теперь матричную запись значений атрибута type. В самом общем случае тип matrix записывается в виде матрицы следующим образом:

\left |
\begin{array}{c}
R' \\ G'\\ B' \\ A' \\ 1
\end{array}
\right | =
\left |
\begin{array}{ccccc}
a_{11} & a_{12} & a_{13} & a_{14} & a_{15} \\
a_{21} & a_{22} & a_{23} & a_{24} & a_{25} \\
a_{31} & a_{32} & a_{33} & a_{34} & a_{35} \\
a_{41} & a_{42} & a_{43} & a_{44} & a_{45} \\
0 & 0 & 0 & 0 & 0
\end{array}
\right | \bullet
\left |
\begin{array}{c}
R \\ G\\ B \\ A \\ 1
\end{array}
\right |

Здесь R', G', B', A' – измененные компоненты изображения в каналах RGBA ( A – прозрачность), R, G, B, A – исходные. Эквивалентная запись для подстановки в SVG – код выглядит так:

type="matrix"
values="a11 a12 a13 a14 a15 a21 a22 a23 a24 a25 a31 a32 a33 a34 a35 a41 a42 a43 a44 a45"

Допускается запись с отступами:

values="a11 a12 a13 a14 a15  a21 a22 a23 a24 a25  a31 a32 a33 a34 a35  a41 a42 a43 a44 a45"

А также запись в столбик, с переносом на новые строки:

values="a11 a12 a13 a14 a15
a21 a22 a23 a24 a25
a31 a32 a33 a34 a35
a41 a42 a43 a44 a45"

Как уже отмечалось, тип matrix не вносит изменений в изображение, это всего лишь форма записи других значений атрибута type. Тип saturate представляется следующей матрицей:

\left |
\begin{array}{c}
R' \\ G'\\ B' \\ A' \\ 1
\end{array}
\right | =
\left |
\begin{array}{ccccc}
0.213 +0.787\cdot s & 0.715 - 0.715\cdot s & 0.072 - 0.072\cdot s & 0 & 0 \\
0.213 - 0.213 \cdot s & 0.715 +0.285\cdot s & 0.072 - 0.072\cdot s & 0 & 0 \\
0.213 - 0.213\cdot s & 0.715 - 0.715\cdot s & 0.072 + 0.928\cdot s & 0 & 0 \\
0 & 0 & 0 & 1 & 0 \\
0 & 0 & 0 & 0 & 0
\end{array}
\right | \bullet
\left |
\begin{array}{c}
R \\ G\\ B \\ A \\ 1
\end{array}
\right |

Где s – одиночное целое действительное число в интервале от 0 до 1.

Тип hueRotate представляется следующей матрицей:

\left |
\begin{array}{c}
R' \\ G'\\ B' \\ A' \\ 1
\end{array}
\right | =
\left |
\begin{array}{ccccc}
a_{11} & a_{12} & a_{13} &  0 & 0 \\
a_{21} & a_{22} & a_{23} & 0  & 0\\
a_{31} & a_{32} & a_{33} & 0  & 0 \\
0 & 0 & 0 & 1 & 0 \\
0 & 0 & 0 & 0 & 1
\end{array}
\right | \bullet
\left |
\begin{array}{c}
R \\ G\\ B \\ A \\ 1
\end{array}
\right |

Элементы a11 a12 a13 и т. д. вычисляются отдельно по следующей схеме:

\left |
\begin{array}{ccc}
a_{11} & a_{12} & a_{13}\\
a_{21} & a_{22} & a_{23}\\
a_{31} & a_{32} & a_{33}
\end{array}
\right | = \\ =
\left |
\begin{array}{ccc}
0.213 & 0.715 & 0.072\\
0.213 & 0.715 & 0.072\\
0.213 & 0.715 & 0.072
\end{array}
\right | + \cos{(angle)} \bullet
\left |
\begin{array}{ccc}
0.787 & -0.715 & -0.072\\
-0.213 & 0.285 & -0.072\\
-0.213 & -0.715 & 0.928
\end{array}
\right |
+ \sin{(angle)} \bullet
\left |
\begin{array}{ccc}
-0.213 & -0.715 & 0.928\\
0.143 & 0.140 & -0.283\\
-0.787 & 0.715 & 0.072
\end{array}
\right |

где angleзначение угла в градусах. Здесь мы сталкиваемся с двумя новыми понятиями – умножением матрицы на число и сложением матриц. Рассмотрим их отдельно. Для умножения матрицы на число k нужно умножить каждый элемент матицы на это число:

k \cdot \left |
\begin{array}{ccc}
a_{11} & a_{12} & a_{13}\\
a_{21} & a_{22} & a_{23}\\
a_{31} & a_{32} & a_{33}
\end{array}
\right | =
\left |
\begin{array}{ccc}
k \cdot a_{11} & k \cdot a_{12} & k \cdot a_{13}\\
k \cdot a_{21} & k \cdot a_{22} & k \cdot a_{23}\\
k \cdot a_{31} & k \cdot a_{32} & k \cdot a_{33}
\end{array}
\right |

Сложение матриц определяется довольно простым образом:

\left |
\begin{array}{ccc}
a_{11} & a_{12} & a_{13}\\
a_{21} & a_{22} & a_{23}\\
a_{31} & a_{32} & a_{33}
\end{array}
\right | +
\left |
\begin{array}{ccc}
b_{11} & b_{12} & b_{13}\\
b_{21} & b_{22} & b_{23}\\
b_{31} & b_{32} & b_{33}
\end{array}
\right | =
\left |
\begin{array}{ccc}
a_{11}+ b_{11} & a_{12}+ b_{12} & a_{13}+ b_{13}\\
a_{21}+ b_{21} & a_{22}+ b_{22} & a_{23}+ b_{23}\\
a_{31}+ b_{31} & a_{32}+ b_{32} & a_{33}+ b_{33}
\end{array}
\right |

Тип luminanceToAlpha, который не содержит возможности изменять какие-либо параметры, представляется так:

\left |
\begin{array}{c}
R' \\ G'\\ B' \\ A' \\ 1
\end{array}
\right | =
\left |
\begin{array}{ccccc}
0 & 0 & 0 &  0 & 0 \\
0 & 0 & 0 & 0  & 0\\
0 & 0 & 0 & 0  & 0 \\
0.2125 & 0.7154 & 0.0721 & 0 & 0 \\
0 & 0 & 0 & 0 & 1
\end{array}
\right | \bullet
\left |
\begin{array}{c}
R \\ G\\ B \\ A \\ 1
\end{array}
\right |

Применять эту форму записи не сложно. Вычислять матрицы можно вручную или при помощи программы Mathcad2Cм. "Трансформации" .. В табл. 9.2 приводятся примеры использования типа matrix.

Таблица 9.2. Фильтр feColorMatrix. Значение matrix.
Код
9.2.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="420" height="450" 
     xmlns="http://www.w3.org/2000/svg" version="1.1">
     <title>Лекция 9. Фильтры. Часть III  </title>
     <desc>
          Пример feColorMatrixM1.svg
     </desc>

<defs>

<filter id="myFilter1" filterUnits="userSpaceOnUse" 
        x="215" y="10" width="186" height="125">
    <feImage xlink:href="sea2.jpg" result="image1"/>
    <feColorMatrix id="color1" in="image1" 
                   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="myFilter2" filterUnits="userSpaceOnUse" 
        x="10" y="155" width="186" height="125">
   <feImage xlink:href="sea2.jpg" result="image1"/>
    <feColorMatrix id="color2" in="image1" 
                   type="matrix" values="1 1 1 1 1
                                         0 1 0 0 0
                                         0 0 1 0 0
                                         0 0 0 1 0"/>
</filter>

<filter id="myFilter3" filterUnits="userSpaceOnUse" 
        x="215" y="155" width="186" height="125">
   <feImage xlink:href="sea2.jpg" result="image1"/>
    <feColorMatrix id="color3" in="image1" 
                   type="matrix" values="1 0 0 0 0
                                         1 1 1 1 1
                                         0 0 1 0 0
                                         0 0 0 1 0"/>
</filter>

<filter id="myFilter4" filterUnits="userSpaceOnUse" 
        x="10" y="300" width="186" height="125">
   <feImage xlink:href="sea2.jpg" result="image1"/>
    <feColorMatrix id="color4" in="image1" 
                   type="matrix" values="1 0 0 0 0
                                         0 1 0 0 0
                                         1 1 1 1 1
                                         0 0 0 1 0"/>
</filter>

<filter id="myFilter5" filterUnits="userSpaceOnUse" 
        x="215" y="300" width="186" height="125">
   <feImage xlink:href="sea2.jpg" result="image1"/>
    <feColorMatrix id="color5" in="image1" 
                   type="matrix" values="1 0 0 0 0
                                         0 1 0 0 0
                                         0 0 1 0 0
                                         1 1 1 1 1"/>
</filter>


</defs>

<rect x="10" y="155" width="186" height="125" 
      filter="url(#myFilter1)"/>
<rect x="10" y="300" width="186" height="125" 
      filter="url(#myFilter2)"/>
<rect x="215" y="10" width="186" height="125" 
      filter="url(#myFilter3)"/>
<rect x="215" y="155" width="186" height="125" 
      filter="url(#myFilter4)"/>
<rect x="215" y="300" width="186" height="125" 
      filter="url(#myFilter5)"/>

<!--Исходное изображение-->
<image x="10" y="10" width="186" height="125" 
       xlink:href="sea2.jpg"/>

<!--Подписи-->
<text x="10" y="145" 
       style="fill: black; font-size: 12px">
       sea2.jpg</text>
<text x="215" y="145" style="fill: black; font-size: 12px">
       Исходная матрица</text>
<text x="10" y="290" style="fill: black; font-size: 12px">
       R = "1 1 1 1 1 "</text>
<text x="215" y="290" style="fill: black; font-size: 12px">
       G = "1 1 1 1 1 "</text>
<text x="10" y="435" style="fill: black; font-size: 12px">
       B = "1 1 1 1 1 "</text>
<text x="215" y="435" style="fill: black; font-size: 12px">
       A = "1 1 1 1 1 "</text>

</svg>
Листинг 9.2.1. Пример feColorMatrixM1.svg
Вид в браузере
Описание
Мы подставили простые значения матрицы, соответствующие цветопередачи в каналах R, G, B и A.
Код
9.2.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="420" height="450" 
     xmlns="http://www.w3.org/2000/svg" version="1.1">
     <title>Лекция 9. Фильтры. Часть III </title>
     <desc>
          Пример feColorMatrixM2.svg
     </desc>

<defs>

<filter id="myFilter1" filterUnits="userSpaceOnUse" 
        x="215" y="10" width="186" height="125">
    <feImage xlink:href="sea2.jpg" result="image1"/>
    <feColorMatrix id="color1" in="image1" 
                   type="matrix" values="0.213 0.715 0.072 0 0
                                         0.213 0.715 0.072 0 0
                                         0.213 0.715 0.072 0 0
                                         0     0     0     1 0"/>
</filter>

<filter id="myFilter2" filterUnits="userSpaceOnUse" 
        x="10" y="155" width="186" height="125">
   <feImage xlink:href="sea2.jpg" result="image1"/>
    <feColorMatrix id="color2" in="image1" 
                   type="matrix" values="0.37 0.572 0.058 0 0
                                         0.17 0.772 0.058 0 0
                                         0.17 0.572 0.258 0 0
                                         0    0     0     1 0"/>
</filter>
<filter id="myFilter3" filterUnits="userSpaceOnUse" 
        x="215" y="155" width="186" height="125">
   <feImage xlink:href="sea2.jpg" result="image1"/>
    <feColorMatrix id="color3" in="image1" 
                   type="matrix" values="0.213 0.429 0.043 0 0
                                         0.128 0.829 0.043 0 0
                                         0.128 0.429 0.443 0 0
                                         0     0     0     1 0"/>
</filter>

</defs>

<rect x="10" y="155" width="186" height="125" 
      filter="url(#myFilter1)"/>
<rect x="10" y="300" width="186" height="125" 
      filter="url(#myFilter2)"/>
<rect x="215" y="10" width="186" height="125" 
      filter="url(#myFilter3)"/>

<!--Исходное изображение-->
<image x="10" y="10" width="186" height="125" 
       xlink:href="sea2.jpg"/>

<!--Подписи-->
<text x="10" y="145" 
       style="fill: black; font-size: 12px">
       sea2.jpg</text>
<text x="215" y="145" style="fill: black; font-size: 12px">
       values="0"</text>
<text x="10" y="290" style="fill: black; font-size: 12px">
       values="0.2"</text>
<text x="215" y="290" style="fill: black; font-size: 12px">
       values="0.4"</text>
</svg>
Листинг 9.2.2. Пример feColorMatrixM2.svg
Вид в браузере
Описание

Вычисление нескольких матриц для значения saturate атрибута type в программе Mathcad.

При values="0":

\left (
\begin{array}{ccccc}
0.213+0.787\cdot 0 & 0.715 - 0.715\cdot 0 & 0.072-0.072\cdot 0 &  0 & 0 \\ 
0.213 – 0.213\cdot 0 & 0.715+0.285\cdot 0 & 0.072 - 0.072\cdot 0 & 0  & 0\\ 
0.213 – 0.213\cdot 0 & 0.715 - 0.715\cdot 0 & 0.072 + 0.928\cdot 0 & 0  & 0\\ 
0 & 0 & 0 & 1 & 0 \\ 
0 & 0 & 0 & 0 & 1 
\end{array}
\right ) =\\ =
\left (
\begin{array}{ccccc}
0.213 & 0.715 & 0.072 &  0 & 0 \\ 
0.213 & 0.715 & 0.072 & 0  & 0\\ 
0.213 & 0.715 & 0.072 & 0  & 0\\ 
0 & 0 & 0 & 1 & 0 \\ 
0 & 0 & 0 & 0 & 1 
\end{array}
\right )

При values="0.2":

\left (
\begin{array}{ccccc}
0.213+0.787\cdot 0.2 & 0.715 - 0.715\cdot 0.2 & 0.072-0.072\cdot 0.2 &  0 & 0 \\ 
0.213 – 0.213\cdot 0.2 & 0.715+0.285\cdot 0.2 & 0.072 - 0.072\cdot 0.2 & 0  & 0\\ 
0.213 – 0.213\cdot 0.2 & 0.715 - 0.715\cdot 0.2 & 0.072 + 0.928\cdot 0.2 & 0  & 0\\ 
0 & 0 & 0 & 1 & 0 \\ 
0 & 0 & 0 & 0 & 1 
\end{array}
\right ) =\\ =
\left (
\begin{array}{ccccc}
0.37 & 0.572 & 0.058 &  0 & 0 \\ 
0.17 & 0.772 & 0.058 & 0  & 0\\ 
0.17 & 0.572 & 0.258 & 0  & 0\\ 
0 & 0 & 0 & 1 & 0 \\ 
0 & 0 & 0 & 0 & 1 
\end{array}
\right )

При values="0.4":

\left (
\begin{array}{ccccc}
0.213+0.787\cdot 0.4 & 0.715 - 0.715\cdot 0.4 & 0.072-0.072\cdot 0.4 &  0 & 0 \\ 
0.213 – 0.213\cdot 0.4 & 0.715+0.285\cdot 0.4 & 0.072 - 0.072\cdot 0.4 & 0  & 0\\ 
0.213 – 0.213\cdot 0.4 & 0.715 - 0.715\cdot 0.4 & 0.072 + 0.928\cdot 0.4 & 0  & 0\\ 
0 & 0 & 0 & 1 & 0 \\ 
0 & 0 & 0 & 0 & 1 
\end{array}
\right ) =\\ =
\left (
\begin{array}{ccccc}
0.213 & 0.429 & 0.043 &  0 & 0 \\ 
0.128 & 0.829 & 0.043 & 0  & 0\\ 
0.128 & 0.429 & 0.443 & 0  & 0\\ 
0 & 0 & 0 & 1 & 0 \\ 
0 & 0 & 0 & 0 & 1 
\end{array}
\right )

Эти значения и были подставлены в код SVG – документа.

Код
9.2.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="420" height="450" 
     xmlns="http://www.w3.org/2000/svg" version="1.1">
     <title>Лекция 9. Фильтры. Часть III </title>
     <desc>
          Пример feColorMatrixM3.svg
     </desc>

<defs>

<filter id="myFilter1" filterUnits="userSpaceOnUse" 
        x="215" y="10" width="186" height="125">
    <feImage xlink:href="sea2.jpg" result="image1"/>
    <feColorMatrix id="color1" in="image1" 
               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="myFilter2" filterUnits="userSpaceOnUse" 
        x="10" y="155" width="186" height="125">
   <feImage xlink:href="sea2.jpg" result="image1"/>
    <feColorMatrix id="color2" in="image1" 
               type="matrix" values="0.784 -0.263 0.479 0 0
                       0.102 1.032 -0.133 0 0
                      -0.369 0.46 0.909 0 0
                       0 0 0 1 0"/>
</filter>


<filter id="myFilter3" filterUnits="userSpaceOnUse" 
        x="215" y="155" width="186" height="125">
   <feImage xlink:href="sea2.jpg" result="image1"/>
    <feColorMatrix id="color3" in="image1" 
               type="matrix" values="0.42 -0.261 0.841 0 0
                       0.231 0.978 -0.209 0 0
                      -0.576 0.979 0.596 0 0
                       0 0 0 1 0"/>
</filter>

</defs>

<rect x="10" y="155" width="186" height="125" 
      filter="url(#myFilter1)"/>
<rect x="10" y="300" width="186" height="125" 
      filter="url(#myFilter2)"/>
<rect x="215" y="10" width="186" height="125" 
      filter="url(#myFilter3)"/>


<!--Исходное изображение-->
<image x="10" y="10" width="186" height="125" 
       xlink:href="sea2.jpg"/>

<!--Подписи-->
<text x="10" y="145" 
       style="fill: black; font-size: 12px">
       sea2.jpg</text>
<text x="215" y="145" style="fill: black; font-size: 12px">
       values="0"</text>
<text x="10" y="290" style="fill: black; font-size: 12px">
       values="30"</text>
<text x="215" y="290" style="fill: black; font-size: 12px">
       values="60"</text>
</svg>
Листинг 9.2.3. Пример feColorMatrixM3.svg
Вид в браузере
Описание

Вычисление нескольких матриц для значения hueRotate атрибута type.

При values="0":

\left (
\begin{array}{ccc}
0.213 & 0.715 & 0.072\\
0.213 & 0.715 & 0.072\\
0.213 & 0.715 & 0.072
\end{array}
\right ) + 
\left (
\begin{array}{ccc}
0.787 & -0.715 & -0.072\\
-0.213 & 0.285 & -0.072\\
-0.213 & -0.715 & 0.928
\end{array}
\right ) \cdot \cos{(0)}
+\\+ \left (
\begin{array}{ccc}
-0.213 & -0.715 & 0.928\\
0.143 & 0.140 & -0.283\\
-0.787 & 0.715 & 0.072
\end{array}
\right ) \cdot \sin{(0)} =
\left (
\begin{array}{ccc}
1 & 0 & 0\\
0 & 1 & 0\\
0 & 0 & 1
\end{array}
\right )

При values="30" Значение угла в радианах ( 1 радиан примерно равен 57 градусам)

\left (
\begin{array}{ccc}
0.213 & 0.715 & 0.072\\
0.213 & 0.715 & 0.072\\
0.213 & 0.715 & 0.072
\end{array}
\right ) + 
\left (
\begin{array}{ccc}
0.787 & -0.715 & -0.072\\
-0.213 & 0.285 & -0.072\\
-0.213 & -0.715 & 0.928
\end{array}
\right ) \cdot \cos{(0.53)}
+\\+ \left (
\begin{array}{ccc}
-0.213 & -0.715 & 0.928\\
0.143 & 0.140 & -0.283\\
-0.787 & 0.715 & 0.072
\end{array}
\right ) \cdot \sin{(0.53)} = \\ =
\left (
\begin{array}{ccc}
0.784 & -0.263 & 0.479\\
0.102 & 1.032 & -0.133\\
-0.369 & 0.46 & 0.909
\end{array}
\right )

При values="60"

\left (
\begin{array}{ccc}
0.213 & 0.715 & 0.072\\
0.213 & 0.715 & 0.072\\
0.213 & 0.715 & 0.072
\end{array}
\right ) + 
\left (
\begin{array}{ccc}
0.787 & -0.715 & -0.072\\
-0.213 & 0.285 & -0.072\\
-0.213 & -0.715 & 0.928
\end{array}
\right ) \cdot \cos{(1.06)}
+\\+ \left (
\begin{array}{ccc}
-0.213 & -0.715 & 0.928\\
0.143 & 0.140 & -0.283\\
-0.787 & 0.715 & 0.072
\end{array}
\right ) \cdot \sin{(1.06)} = \\ =
\left (
\begin{array}{ccc}
0.42 & -0.261 & 0.841\\
0.231 & 0.978 & -0.209\\
-0.576 & 0.979 & 0.596
\end{array}
\right )
Код
9.2.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="210" height="350" 
     xmlns="http://www.w3.org/2000/svg" version="1.1">
     <title>Лекция 9. Фильтры. Часть III </title>
     <desc>
          Пример feColorMatrixM4.svg
     </desc>

<defs>

<filter id="myFilter" filterUnits="userSpaceOnUse" 
        x="10" y="175" width="186" height="125">
    <feImage xlink:href="#MyImage" result="image1"/>
    <feColorMatrix id="color" in="image1" 
               type="matrix" values="0 0 0 0 0
                        0 0 0 0 0
                        0 0 0 0 0
                        0.2125 0.7154 0.0721 0 0"/>
</filter>

<image id="MyImage" x="10" y="175" width="186" height="125" 
       xlink:href="sea2.jpg"/>



</defs>
<rect x="0" y="0" width="200" height="200" 
      filter="url(#myFilter)"/>

<!--Исходное изображение-->
<image x="10" y="10" width="186" height="125" 
       xlink:href="sea2.jpg"/>

</svg>
Листинг 9.2.4. Пример feColorMatrixM4.svg
Вид в браузере
Описание
Задаваемая матрица эквивалентна типу luminanceToAlpha
< Лекция 8 || Лекция 9: 12345 || Лекция 10 >