15 Filter Effects


Contents


15.1 Introduction

This chapter describes SVG's declarative filter effects feature set, which when combined with the 2D power of SVG can describe much of the common artwork on the Web in such a way that client-side generation and alteration can be performed easily.

A filter effect consists of a series of graphics operations that are applied to a given source graphic to produce a modified graphical result. The result of the filter effect is rendered to the target device instead of the original source graphic. The following illustrates the process:

Image showing source graphic transformed by filter effect

View this example as SVG (SVG-enabled browsers only)
 

Filter effects are defined by 'filter' elements. To apply a filter effect to a graphics element or a container element, you set the value of the 'filter' property on the given element such that it references the filter effect.

Each 'filter' element contains a set of filter primitives as its children. Each filter primitive performs a single fundamental graphical operation (e.g., a blur or a lighting effect) on one or more inputs, producing a graphical result. Because most of the filter primitives represent some form of image processing, in most cases the output from a filter primitive is a single RGBA image.

The original source graphic or the result from a filter primitive can be used as input into one or more other filter primitives. A common application is to use the source graphic multiple times. For example, a simple filter could replace one graphic by two by adding a black copy of original source graphic offset to create a drop shadow. In effect, there are now two layers of graphics, both with the same original source graphics.

When applied to grouping elements such as 'g', the 'filter' property applies to the contents of the group as a whole. The group's children do not render to the screen directly; instead, the graphics commands necessary to render the children are stored temporarily. Typically, the graphics commands are executed as part of the processing of the referenced 'filter' element via use of the keywords SourceGraphic or SourceAlpha. Filter effects can be applied to grouping elements with no content (e.g., an empty 'g' element), in which case the SourceGraphic or SourceAlpha consist of a fully transparent rectangle that is the size of the filter effects region.


15.2 An example

The following shows an example of a filter effect.

Example filters01 - introducing filter effects.

<?xml version="1.0"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20001102//EN" 
              "http://www.w3.org/TR/2000/CR-SVG-20001102/DTD/svg-20001102.dtd">
<svg width="7.5cm" height="5cm" viewBox="0 0 200 120">
  <title>Example filters01.svg - introducing filter effects</title>
  <desc>An example which combines multiple filter primitives
        to produce a 3D lighting effect on a graphic consisting
        of the string "SVG" sitting on top of oval filled in red
        and surrounded by an oval outlined in red.</desc>
  <defs>
    <filter id="MyFilter">
      <feGaussianBlur in="SourceAlpha" stdDeviation="4" result="blur"/>
      <feOffset in="blur" dx="4" dy="4" result="offsetBlur"/>
      <feSpecularLighting in="blur" surfaceScale="5" specularConstant="1" 
                          specularExponent="10" style="lighting-color:white" 
                          result="specOut">
        <fePointLight x="-5000" y="-10000" z="20000"/>
      </feSpecularLighting>
      <feComposite in="specOut" in2="SourceAlpha" operator="in" result="specOut"/>
      <feComposite in="SourceGraphic" in2="specOut" operator="arithmetic" 
                   k1="0" k2="1" k3="1" k4="0" result="litPaint"/>
      <feMerge>
        <feMergeNode in="offsetBlur"/>
        <feMergeNode in="litPaint"/>
      </feMerge>
    </filter>
  </defs>
  <rect x="1" y="1" width="198" height="118" style="fill:#888888; stroke:blue"/>
  <g style="filter:url(#MyFilter)">
	  <g>
      <path style="fill:none; stroke:#D90000; stroke-width:10"
            d="M50,90 C0,90 0,30 50,30 L150,30 C200,30 200,90 150,90 z" />
      <path style="fill:#D90000"
            d="M60,80 C30,80 30,40 60,40 L140,40 C170,40 170,80 140,80 z" />
      <g style="fill:#FFFFFF; stroke:black; font-size:45; font-family:Verdana">
        <text x="52" y="76">SVG</text>
      </g>
    </g>
  </g>
</svg>
Example filters01
Example filters01 - introducing filter effects

View this example as SVG (SVG-enabled browsers only)
 

The filter effect used in the example above is repeated here with reference numbers in the left column before each of the six filter primitives:



1
2
3




4
5

6
<filter id="MyFilter">
  <desc>Produces a 3D lighting effect.</desc>
  <feGaussianBlur in="SourceAlpha" stdDeviation="4" result="blur"/>
  <feOffset in="blur" dx="4" dy="4" result="offsetBlur"/>
  <feSpecularLighting in="blur" surfaceScale="5" specularConstant="1" 
                      specularExponent="10" style="lighting-color:white" 
                      result="specOut">
    <fePointLight x="-5000" y="-10000" z="20000"/>
  </feSpecularLighting>
  <feComposite in="specOut" in2="SourceAlpha" operator="in" result="specOut"/>
  <feComposite in="SourceGraphic" in2="specOut" operator="arithmetic" 
               k1="0" k2="1" k3="1" k4="0" result="litPaint"/>
  <feMerge>
    <feMergeNode in="offsetBlur"/>
    <feMergeNode in="litPaint"/>
  </feMerge>
</filter>

The following pictures show the intermediate image results from each of the six filter elements:

filters01 - original source graphic
Source graphic

 

filters01 - after filter element 1
After filter primitive 1

 

filters01 - after filter element 2
After filter primitive 2

 

filters01 - after filter element 3
After filter primitive 3

  
   

filters01 - after filter element 4
After filter primitive 4

 

filters01 - after filter element 5
After filter primitive 5

 

filters01 - after filter element 6
After filter primitive 6

  1. Filter primitive 'feGaussianBlur' takes input SourceAlpha, which is the alpha channel of the source graphic. The result is stored in a temporary buffer named "blur". Note that "blur" is used as input to both filter primitives 2 and 3.
  2. Filter primitive 'feOffset' takes buffer "blur", shifts the result in a positive direction in both x and y, and creates a new buffer named "offsetBlur". The effect is that of a drop shadow.
  3. Filter primitive 'feSpecularLighting', uses buffer "blur" as a model of a surface elevation and generates a lighting effect from a single point source. The result is stored in buffer "specOut".
  4. Filter primitive 'feComposite' masks out the result of filter primitive 3 by the original source graphics alpha channel so that the intermediate result is no bigger than the original source graphic.
  5. Filter primitive 'feComposite' composites the result of the specular lighting with the original source graphic.

  6. Filter primitive 'feMerge' composites two layers together. The lower layer consists of the drop shadow result from filter primitive 2. The upper layer consists of the specular lighting result from filter primitive 5.


15.3 The 'filter' element

The description of the 'filter' element follows:

<!ENTITY % filterExt "" >
<!ELEMENT filter (%descTitleMetadata;,(feBlend|feFlood|
  feColorMatrix|feComponentTransfer|
  feComposite|feConvolveMatrix|feDiffuseLighting|feDisplacementMap|
  feGaussianBlur|feImage|feMerge|
  feMorphology|feOffset|feSpecularLighting|
  feTile|feTurbulence|
  animate|set
  %filterExt;)*) >
<!ATTLIST filter
  %stdAttrs;
  %xlinkRefAttrs;
  xlink:href %URI; #IMPLIED
  %langSpaceAttrs;
  externalResourcesRequired %Boolean; #IMPLIED
  class %ClassList; #IMPLIED
  style %StyleSheet; #IMPLIED
  %PresentationAttributes-All;
  filterUnits (userSpaceOnUse | objectBoundingBox) #IMPLIED
  primitiveUnits (userSpaceOnUse | objectBoundingBox) #IMPLIED
  x %Coordinate; #IMPLIED
  y %Coordinate; #IMPLIED
  width %Length; #IMPLIED
  height %Length; #IMPLIED
  filterRes CDATA #IMPLIED >

Attribute definitions:

filterUnits = "userSpaceOnUse | objectBoundingBox"
See Filter effects region.
primitiveUnits = "userSpaceOnUse | objectBoundingBox"
Specifies the coordinate system for the various length values within the filter primitives.
If primitiveUnits="userSpaceOnUse", any length values within the filter definitions represent values in the current user coordinate system in place at the time when the 'filter' element is referenced (i.e., the user coordinate system for the element referencing the 'filter' element via a 'filter' property).
If primitiveUnits="objectBoundingBox", then any length values within the filter definitions represent fractions or percentages of the bounding box on the referencing element (see Object bounding box units).
If attribute primitiveUnits is not specified, then the effect is as if a value of userSpaceOnUse were specified.
Animatable: yes.
x = "x-coordinate"
See Filter effects region.
y = "y-coordinate"
See Filter effects region.
width = "length"
See Filter effects region.
height = "length"
See Filter effects region.
filterRes = "<number> [<number>]"
See Filter effects region.
xlink:href = "<uri>"
A URI reference to another 'filter' element within the current SVG document fragment. Any attributes which are defined on the referenced 'filter' element which are not defined on this element are inherited by this element. If this element has no defined filter nodes, and the referenced element has defined filter nodes (possibly due to its own href attribute), then this element inherits the filter nodes defined from the referenced 'filter' element. Inheritance can be indirect to an arbitrary level; thus, if the referenced 'filter' element inherits attributes or its filter node specification due to its own href attribute, then the current element can inherit those attributes or filter node specifications.
Animatable: yes.
Attributes defined elsewhere:
%stdAttrs;, %langSpaceAttrs;, %xlinkRefAttrs; externalResourcesRequired, %PresentationAttributes-All;.

15.4 The 'filter' property

The description of the 'filter' property is as follows:

'filter'
Value:   <uri> | none | inherit
Initial:   none
Applies to:   graphics and container elements
Inherited:   no
Percentages:   N/A
Media:   visual
Animatable:   yes
<uri>
A URI reference to a 'filter' element which defines the filter effects that shall be applied to this element.
none
Do not apply any filter effects to this element.

15.5 Filter effects region

A 'filter' element can define a region on the canvas on which a given filter effect applies and can provide a resolution for any intermediate continuous tone images used to process any raster-based filter primitives. The 'filter' element has the following attributes which work together to define the filter effects region:

For performance reasons on display devices, it is recommended that the filter effect region is designed to match pixel-for-pixel with the background.

It is often necessary to provide padding space because the filter effect might impact bits slightly outside the tight-fitting bounding box on a given object. For these purposes, it is possible to provide negative percentage values for x, y and percentages values greater than 100% for width, height. For example, x="-10%" y="-10%" width="120%" height="120%".

15.6 Accessing the background image

Two possible pseudo input images for filter effects are BackgroundImage and BackgroundAlpha, which each represent an image snapshot of the canvas under the filter region at the time that the <filter> element is invoked. BackgroundImage represents both the color values and alpha channel of the canvas (i.e., RGBA pixel values), whereas BackgroundAlpha represents only the alpha channel.

Implementations of SVG user agents often will need to maintain supplemental background image buffers in order to support the BackgroundImage and BackgroundAlpha pseudo input images. Sometimes, the background image buffers will contain an in-memory copy of the accumulated painting operations on the current canvas.

Because in-memory image buffers can take up significant system resources, SVG content must explicitly indicate to the SVG user agent that the document needs access to the background image before BackgroundImage and BackgroundAlpha pseudo input images can be used. The property which enables access to the background image is 'enable-background':

'enable-background'
Value:   accumulate | new [ <x> <y> <width> <height> ] | inherit
Initial:   accumulate
Applies to:   container elements
Inherited:   no
Percentages:   N/A
Media:   visual
Animatable:   no

'enable-background' is only applicable to container elements and specifies how the SVG user agents manages the accumulation of the background image.

A value of new indicates two things:

A meaning of enable-background: accumulate (the initial/default value) depends on context:

If a filter effect specifies either the BackgroundImage or the BackgroundAlpha pseudo input images and no ancestor container element has a property value of 'enable-background:new', then the background image request is technically in error. Processing will proceed without interruption (i.e., no error message) and a fully transparent image shall be provided in response to the request.

The optional <x>,<y>,<width>,<height> parameters on the new value indicate the subregion of user space where access to the background image is allowed to happen. These parameters enable the SVG user agent potentially to allocate smaller temporary image buffers than the default values, which might require the SVG user agent to allocate buffers as large as the current viewport. Thus, the values <x>,<y>,<width>,<height> act as a clipping rectangle on the background image canvas. Negative values for <width> or <height> are an error (see Error processing). If more than zero but less than four of the values <x>,<y>,<width> and <height> are specified or if zero values are specified for <width> or <height>, BackgroundImage and BackgroundAlpha are processed as if background image processing were not enabled.

15.7 Filter primitives overview

15.7.1 Overview

This section describes the various filter primtives that can be assembed to achieve a particular filter effect.

Unless otherwise stated, all image filters operate on linear premultiplied RGBA samples. Filters which work more naturally on non-premultiplied data (feColorMatrix and feComponentTransfer) will temporarily undo and redo premultiplication as specified. All raster effect filtering operations take 1 to N input RGBA images, additional attributes as parameters, and produce a single output RGBA image.

The RGBA result from each filter primitive will be clamped into the allowable ranges for colors and opacity values. Thus, for example, the result from a given filter primitives will have any negative color values or opacity values adjusted up to color/opacity of zero.

15.7.2 Common attributes

The following attributes are available for most of the filter primitives:

<!ENTITY % filter_primitive_attributes
  "x %Coordinate; #IMPLIED
   y %Coordinate; #IMPLIED
   width %Length; #IMPLIED
   height %Length; #IMPLIED
   result CDATA #IMPLIED" >

<!ENTITY % filter_primitive_attributes_with_in
  "%filter_primitive_attributes;
   in CDATA #IMPLIED">

Attribute definitions:

x = "<coordinate>"
The minimum x coordinate for the subregion which restricts calculation and rendering of the given filter primitive. See filter primitive subregion.
Animatable: yes.
y = "<coordinate>"
The minimum y coordinate for the subregion which restricts calculation and rendering of the given filter primitive. See filter primitive subregion. Animatable: yes.
width = "<length>"
The width of the subregion which restricts calculation and rendering of the given filter primitive. See filter primitive subregion.
A negative value is an error (see Error processing). A value of zero disables the effect of the given filter primitive (i.e., the result is a fully transparent image).
Animatable: yes.
height = "<length>"
The height of the subregion which restricts calculation and rendering of the given filter primitive. See filter primitive subregion.
A negative value is an error (see Error processing). A value of zero disables the effect of the given filter primitive (i.e., the result is a fully transparent image).
Animatable: yes.
result = "<filter-primitive-reference>"
Assigned name for this filter primitive. If supplied, then graphics that result from processing this filter primitive can be referenced by an in attribute on a subsequent filter primitive within the same 'filter' element. If no value is provided, the output will only be available for re-use as the implicit input into the next filter primitive if that filter primitive provides no value for its in attribute.
Note that a <filter-primitive-reference> is not an XML ID; instead, a <filter-primitive-reference> is only meaningful within a given 'filter' element and thus have only local scope. It is legal for the same <filter-primitive-reference> to appear multiple times within the same 'filter' element. When referenced, the <filter-primitive-reference> will use the closest preceding filter primitive with the given result.
Animatable: yes.
in = "SourceGraphic | SourceAlpha | BackgroundImage | BackgroundAlpha | FillPaint | StrokePaint | <filter-primitive-reference>"
Identifies input for the given filter primitive. The value can be either one of six keywords or can be a string which matches a previous result attribute value within the same 'filter' element. If no value is provided and this is the first filter primitive, then this filter primitive will use SourceGraphic as its input. If no value is provided and this is a subsequent filter primitive, then this filter primitive will use the result from the previous filter primitive as its input.

If the value for result appears multiple times within a given 'filter' element, then a reference to that result will use the closest preceding filter primitive with the given value for attribute result. Forward references to results are an error.

Definitions for the six keywords:
SourceGraphic
This keyword represents the graphics elements that were the original input into the 'filter' element. For raster effects filter primitives, the graphics elements will be rasterized into an initially clear RGBA raster in image space. Pixels left untouched by the original graphic will be left clear. The image is specified to be rendered in linear RGBA pixels. The alpha channel of this image captures any anti-aliasing specified by SVG. (Since the raster is linear, the alpha channel of this image will represent the exact percent coverage of each pixel.)
SourceAlpha
This keyword represents the graphics elements that were the original input into the 'filter' element. SourceAlpha has all of the same rules as SourceGraphic except that only the alpha channel is used. The input image is an RGBA image consisting of implicitly black color values for the RGB channels, but whose alpha channel is the same as SourceGraphic. If this option is used, then some implementations might need to rasterize the graphics elements in order to extract the alpha channel.
BackgroundImage
This keyword represents an image snapshot of the canvas under the filter region at the time that the 'filter' element was invoked. See Accessing the background image.
BackgroundAlpha
Same as BackgroundImage except only the alpha channel is used. See SourceAlpha and Accessing the background image.
FillPaint
This keyword represents the value of the 'fill' property on the target element for the filter effect. The FillPaint image has conceptually infinite extent. Frequently this image is opaque everywhere, but it might not be if the "paint" itself has alpha, as in the case of an alpha gradient or transparent pattern.
StrokePaint
This keyword represents the value of the 'stroke' property on the target element for the filter effect. The StrokePaint image has conceptually infinite extent. Frequently this image is opaque everywhere, but it might not be if the "paint" itself has alpha, as in the case of an alpha gradient or transparent pattern.
Animatable: yes.

15.7.3 Filter primitive subregion

All filter primitives have attributes x, y, width and height which identify a subregion which restricts calculation and rendering of the given filter primitive. These attributes are defined according to the same rules as other filter primitives' coordinate and length attributes.

x, y, width and height default to the union (i.e., tightest fitting bounding box) of the subregions defined for all referenced nodes. If there are no referenced nodes (e.g., for 'feImage' or 'feTurbulence', which have no specified value for in, or if in="SourceGraphic") or for 'feTile' (which is special), the default subregion is 0%,0%,100%,100%, where percentages are relative to the dimensions of the filter region.

x, y, width and height act as a hard clip clipping rectangle.

All intermediate offscreens are defined to not exceed the intersection of x, y, width and height with the filter region. The filter region and any of the x, y, width and height subregions are to be set up such that all offscreens are made big enough to accommodate any pixels which even partly intersect with either the filter region or the x,y,width,height subregions.

'feImage' scales the referenced image to fit exactly into the subregion specified by x, y, width and height.

'feTile' references a previous filter primitive and then stitches the tiles together based on the x, y, width and height values of the referenced filter primitive.

15.8 Light source elements and properties

15.8.1 Introduction

The following sections define the elements that define a light source, 'feDistantLight', 'fePointLight' and 'feSpotLight', and property 'lighting-color', which defines the color of the light.

15.8.2 Light source 'feDistantLight'

<!ELEMENT feDistantLight (animate|set)* >
<!ATTLIST feDistantLight
  %stdAttrs;
  azimuth %Number; #IMPLIED
  elevation %Number; #IMPLIED >

Attribute definitions:

azimuth = "<number>"
Direction angle for the light source on the XY plane, in degrees.
If the attribute is not specified, then the effect is as if a value of 0 were specified.
Animatable: yes.
elevation = "<number>"
Direction angle for the light source on the YZ plane, in degrees.
If the attribute is not specified, then the effect is as if a value of 0 were specified.
Animatable: yes.
Attributes defined elsewhere:
%stdAttrs;.

15.8.3 Light source 'fePointLight'

<!ELEMENT fePointLight (animate|set)* >
<!ATTLIST fePointLight
  %stdAttrs;
  x %Number; #IMPLIED
  y %Number; #IMPLIED
  z %Number; #IMPLIED >

Attribute definitions:

x = "<number>"
X location for the light source.
If the attribute is not specified, then the effect is as if a value of 0 were specified.
Animatable: yes.
y = "<number>"
Y location for the light source.
If the attribute is not specified, then the effect is as if a value of 0 were specified.
Animatable: yes.
z = "<number>"
Z location for the light source.
If the attribute is not specified, then the effect is as if a value of 0 were specified.
Animatable: yes.
Attributes defined elsewhere:
%stdAttrs;.

15.8.4 Light source 'feSpotLight'

<!ELEMENT feSpotLight (animate|set)* >
<!ATTLIST feSpotLight
  %stdAttrs;
  x %Number; #IMPLIED
  y %Number; #IMPLIED
  z %Number; #IMPLIED
  pointsAtX %Number; #IMPLIED
  pointsAtY %Number; #IMPLIED
  pointsAtZ %Number; #IMPLIED
  specularExponent %Number; #IMPLIED
  limitingConeAngle %Number; #IMPLIED >

Attribute definitions:

x = "<number>"
X location for the light source.
If the attribute is not specified, then the effect is as if a value of 0 were specified.
Animatable: yes.
y = "<number>"
Y location for the light source.
If the attribute is not specified, then the effect is as if a value of 0 were specified.
Animatable: yes.
z = "<number>"
Z location for the light source.
If the attribute is not specified, then the effect is as if a value of 0 were specified.
Animatable: yes.
pointsAtX = "<number>"
X location of the point at which the light source is pointing.
If the attribute is not specified, then the effect is as if a value of 0 were specified.
Animatable: yes.
pointsAtY = "<number>"
Y location of the point at which the light source is pointing.
If the attribute is not specified, then the effect is as if a value of 0 were specified.
Animatable: yes.
pointsAtZ = "<number>"
Z location of the point at which the light source is pointing.
If the attribute is not specified, then the effect is as if a value of 0 were specified.
Animatable: yes.
specularExponent = "<number>"
Exponent value controlling the focus for the light source.
If the attribute is not specified, then the effect is as if a value of 1 were specified.
Animatable: yes.
limitingConeAngle = "<number>"
A limiting cone which restricts the region where the light is projected. No light is projected outside the cone. limitingConeAngle represents the angle between the spot light axis (i.e. the axis between the light source and the point to which it is pointing at) and the spot light cone. User agents should apply a smoothing technique such as anti-aliasing at the boundary of the cone.
If no value is specified, then no limiting cone will be applied.
Animatable: yes.
Attributes defined elsewhere:
%stdAttrs;.

15.8.5 The 'lighting-color' property

The 'lighting-color' property defines the color of the light source for filter primitives 'feDiffuseLighting' and 'feSpecularLighting'.

'lighting-color'
Value:   currentColor |
<color> [icc-color(<name>[,<icccolorvalue>]*)] |
inherit
Initial:   white
Applies to:   'feDiffuseLighting' and 'feSpecularLighting' elements
Inherited:   no
Percentages:   N/A
Media:   visual
Animatable:   yes

15.9 Filter primitive 'feBlend'

This filter composites two objects together using commonly used imaging software blending modes. It performs a pixel-wise combination of two input images.

<!ELEMENT feBlend (animate|set)* >
<!ATTLIST feBlend
  %stdAttrs;
  %filter_primitive_attributes_with_in;
  in2 CDATA #REQUIRED
  mode (normal | multiply | screen | darken | lighten) "normal" >

Attribute definitions:

mode = "normal | multiply | screen | darken | lighten"
One of the image blending modes (see table below). Default is: normal.
Animatable: yes.
in2 = "(see in attribute)"
The second input image to the blending operation. This attribute can take on the same values as the in attribute.
Animatable: yes.
Attributes defined elsewhere:
%stdAttrs;, %filter_primitive_attributes_with_in;.

For all feBlend modes, the result opacity is computed as follows:

qr = 1 - (1-qa)*(1-qb)

For the compositing formulas below, the following definitions apply:

cr = Result color (RGB) - premultiplied 
qa = Opacity value at a given pixel for image A 
qb = Opacity value at a given pixel for image B 
ca = Color (RGB) at a given pixel for image A - premultiplied 
cb = Color (RGB) at a given pixel for image B - premultiplied 

The following table provides the list of available image blending modes:

Image Blending Mode Formula for computing result color
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)

Example feBlend shows examples of the five blend modes.

<?xml version="1.0"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20001102//EN" 
          "http://www.w3.org/TR/2000/CR-SVG-20001102/DTD/svg-20001102.dtd">
<svg width="5cm" height="5cm" viewBox="0 0 500 500">
  <title>Example feBlend - Examples of feBlend modes</title>
  <desc>Five text strings blended into a gradient,
        with one text string for each of the five feBlend modes.</desc>
  <defs>
    <linearGradient id="MyGradient" gradientUnits="userSpaceOnUse"
            x1="100" y1="0" x2="300" y2="0">
      <stop offset="0" style="stop-color:#000000"/>
      <stop offset=".33" style="stop-color:#ffffff"/>
      <stop offset=".67" style="stop-color:#ff0000"/>
      <stop offset="1" style="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>
  <rect style="fill:none; stroke:blue" 
        x="1" y="1" width="498" height="498"/>
  <g style="enable-background: new">
    <rect x="100" y="20" width="300" height="460" style="fill:url(#MyGradient)"/>
    <g style="font-family:Verdana; font-size:75; fill:#888888; fill-opacity:.6">
      <text x="50" y="90" style="filter:url(#Normal)">Normal</text>
      <text x="50" y="180" style="filter:url(#Multiply)">Multiply</text>
      <text x="50" y="270" style="filter:url(#Screen)">Screen</text>
      <text x="50" y="360" style="filter:url(#Darken)">Darken</text>
      <text x="50" y="450" style="filter:url(#Lighten)">Lighten</text>
    </g>
  </g>
</svg>
Example feBlend
Example feBlend - Examples of feBlend modes

View this example as SVG (SVG-enabled browsers only)
 

15.10 Filter primitive 'feColorMatrix'

This filter applies a matrix transformation:

| R' |     | a00 a01 a02 a03 a04 |   | R |

| G' |     | a10 a11 a12 a13 a14 |   | G |

| B' |  =  | a20 a21 a22 a23 a24 | * | B |

| A' |     | a30 a31 a32 a33 a34 |   | A |

| 1  |     |  0   0   0   0   1  |   | 1 |

on the RGBA color and alpha values of every pixel on the input graphics to produce a result with a new set of RGBA color and alpha values.

The calculations are performed on non-premultiplied color values. If the input graphics consists of premultiplied color values, those values are automatically converted into non-premultiplied color values for this operation.

These matrices often perform an identity mapping in the alpha channel. If that is the case, an implementation can avoid the costly undoing and redoing of the premultiplication for all pixels with A = 1.

<!ELEMENT feColorMatrix (animate|set)* >
<!ATTLIST feColorMatrix
  %stdAttrs;
  %filter_primitive_attributes_with_in;
  type (matrix | saturate | hueRotate | luminanceToAlpha) "matrix"
  values CDATA #IMPLIED >

Attribute definitions:

type = "matrix | saturate | hueRotate | luminanceToAlpha"
Indicates the type of matrix operation. The keyword matrix indicates that a full 5x4 matrix of values will be provided. The other keywords represent convenience shortcuts to allow commonly used color operations to be performed without specifying a complete matrix.
Animatable: yes.
values = "list of <number>s"
The contents of values depends on the value of attribute type:
  • For type="matrix", values is a list of 20 matrix values (a00 a01 a02 a03 a04 a10 a11 ... a34), separated by whitespace and/or a comma. For example, the identity matrix could be expressed as:
    type="matrix" 
    values="1 0 0 0 0  0 1 0 0 0  0 0 1 0 0  0 0 0 1 0"
    
  • For type="saturate", values is a single real number value (0 to 1) or one percentage value (e.g., 50%). A saturate operation is equivalent to the following matrix operation:
    | R' |     |0.213+0.787s  0.715-0.715s  0.072-0.072s 0  0 |   | R |
    
    | G' |     |0.213-0.213s  0.715+0.285s  0.072-0.072s 0  0 |   | G |
    
    | B' |  =  |0.213-0.213s  0.715-0.715s  0.072+0.928s 0  0 | * | B |
    
    | A' |     |           0            0             0  1  0 |   | A |
    
    | 1  |     |           0            0             0  0  1 |   | 1 |
    
  • For type="hueRotate", values is a single one real number value (degrees). A hueRotate operation is equivalent to the following matrix operation:
    | R' |     | a00  a01  a02  0  0 |   | R |
    
    | G' |     | a10  a11  a12  0  0 |   | G |
    
    | B' |  =  | a20  a21  a22  0  0 | * | B |
    
    | A' |     | 0    0    0    1  0 |   | A |
    
    | 1  |     | 0    0    0    0  1 |   | 1 |
    
    where the terms a00, a01, etc. are calculated as follows:
    | a01 a01 a02 |    [+0.213 +0.715 +0.072]
    | a10 a11 a12 | =  [+0.213 +0.715 +0.072] +
    | a20 a21 a22 |    [+0.213 +0.715 +0.072]
    
                            [+0.787 -0.715 -0.072]
    cos(hueRotate value) *  [-0.212 +0.285 -0.072] +
                            [-0.213 -0.715 +0.928]
    
                            [-0.213 -0.715+0.928]
    sin(hueRotate value) *  [+0.143 +0.140-0.283]
                            [-0.787 +0.715+0.072]
    
    Thus, the upper left term of the hue matrix turns out to be:
    .213 + cos(hueRotate value)*.787 - sin(hueRotate value)*.213
    
  • For type="luminanceToAlpha", values is not applicable. A luminanceToAlpha operation is equivalent to the following matrix operation:
       | R' |     |      0        0        0  0  0 |   | R |
    
       | G' |     |      0        0        0  0  0 |   | G |
    
       | B' |  =  |      0        0        0  0  0 | * | B |
    
       | A' |     | 0.2125   0.7154   0.0721  0  0 |   | A |
    
       | 1  |     |      0        0        0  0  1 |   | 1 |
    
If the attribute is not specified, then the default behavior depends on the value of attribute type. If type="matrix", then this attribute defaults to the identity matrix. If type="saturate", then this attribute defaults to the value 1. If type="hueRotate", then this attribute defaults to the value 0.
Animatable: yes.
Attributes defined elsewhere:
%stdAttrs;, %filter_primitive_attributes_with_in;.

Example feColorMatrix shows examples of the four types of feColorMatrix operations.

<?xml version="1.0"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20001102//EN" 
          "http://www.w3.org/TR/2000/CR-SVG-20001102/DTD/svg-20001102.dtd">
<svg width="8cm" height="5cm" viewBox="0 0 800 500">
  <title>Example feColorMatrix - Examples of feColorMatrix operations</title>
  <desc>Five text strings showing the effects of feColorMatrix: 
        an unfiltered text string acting as a reference, 
        use of the feColorMatrix matrix option to convert to grayscale,
        use of the feColorMatrix saturate option,
        use of the feColorMatrix hueRotate option,
        and use of the feColorMatrix luminanceToAlpha option.</desc>
  <defs>
    <linearGradient id="MyGradient" gradientUnits="userSpaceOnUse"
            x1="100" y1="0" x2="500" y2="0">
      <stop offset="0" style="stop-color:#ff00ff"/>
      <stop offset=".33" style="stop-color:#88ff88"/>
      <stop offset=".67" style="stop-color:#2020ff"/>
      <stop offset="1" style="stop-color:#d00000"/>
    </linearGradient>
    <filter id="Matrix" filterUnits="objectBoundingBox" 
            x="0%" y="0%" width="100%" height="100%">
      <feColorMatrix type="matrix" in="SourceGraphic"
           values=".33 .33 .33 0 0 
                   .33 .33 .33 0 0 
                   .33 .33 .33 0 0 
                   .33 .33 .33 0 0"/>
    </filter>
    <filter id="Saturate40" filterUnits="objectBoundingBox" 
            x="0%" y="0%" width="100%" height="100%">
      <feColorMatrix type="saturate" in="SourceGraphic" values="40%"/>
    </filter>
    <filter id="HueRotate90" filterUnits="objectBoundingBox" 
            x="0%" y="0%" width="100%" height="100%">
      <feColorMatrix type="hueRotate" in="SourceGraphic" values="90"/>
    </filter>
    <filter id="LuminanceToAlpha" filterUnits="objectBoundingBox" 
            x="0%" y="0%" width="100%" height="100%">
      <feColorMatrix type="luminanceToAlpha" in="SourceGraphic" result="a"/>
      <feComposite in="SourceGraphic" in2="a" operator="in" />
    </filter>
  </defs>
  <rect style="fill:none; stroke:blue" 
        x="1" y="1" width="798" height="498"/>
  <g style="font-family:Verdana; font-size:75; 
            font-weight:bold; fill:url(#MyGradient)">
    <rect x="100" y="0" width="500" height="20" />
    <text x="100" y="90">Unfiltered</text>
    <text x="100" y="190" style="filter:url(#Matrix)">Matrix</text>
    <text x="100" y="290" style="filter:url(#Saturate20)">Saturate</text>
    <text x="100" y="390" style="filter:url(#HueRotate90)">HueRotate</text>
    <text x="100" y="490" style="filter:url(#LuminanceToAlpha)">Luminance</text>
  </g>
</svg>
Example feColorMatrix
Example feColorMatrix - Examples of feColorMatrix operations

View this example as SVG (SVG-enabled browsers only)
 

15.11 Filter primitive 'feComponentTransfer'

This filter primitive performs component-wise remapping of data as follows:

R' = feFuncR( R )
G' = feFuncG( G )
B' = feFuncB( B )
A' = feFuncA( A )

for every pixel. It allows operations like brightness adjustment, contrast adjustment, color balance or thresholding.

The calculations are performed on non-premultiplied color values. If the input graphics consists of premultiplied color values, those values are automatically converted into non-premultiplied color values for this operation. (Note that the undoing and redoing of the premultiplication can be avoided if feFuncA is the identity transform and all alpha values on the source graphic are set to 1.)

<!ELEMENT feComponentTransfer (feFuncR?,feFuncG?,feFuncB?,feFuncA?) >
<!ATTLIST feComponentTransfer
  %stdAttrs;
  %filter_primitive_attributes_with_in; >

<!ENTITY % component_transfer_function_attributes
  "type (identity | table | discrete | linear | gamma) #REQUIRED
   tableValues CDATA #IMPLIED
   slope %Number; #IMPLIED
   intercept %Number; #IMPLIED
   amplitude %Number; #IMPLIED
   exponent %Number; #IMPLIED
   offset %Number; #IMPLIED" >

<!ELEMENT feFuncR (animate|set)* >
<!ATTLIST feFuncR
  %stdAttrs;
  %component_transfer_function_attributes; >

<!ELEMENT feFuncG (animate|set)* >
<!ATTLIST feFuncG
  %stdAttrs;
  %component_transfer_function_attributes; >

<!ELEMENT feFuncB (animate|set)* >
<!ATTLIST feFuncB
  %stdAttrs;
  %component_transfer_function_attributes; >

<!ELEMENT feFuncA (animate|set)* >
<!ATTLIST feFuncA
  %stdAttrs;
  %component_transfer_function_attributes; >
The specification of the transfer functions is defined by the sub-elements to 'feComponentTransfer':
'feFuncR', transfer function for red component of the input graphic
'feFuncG', transfer function for green component of the input graphic
'feFuncB', transfer function for blue component of the input graphic
'feFuncA', transfer function for alpha component of the input graphic

The attributes below apply to sub-elements 'feFuncR', 'feFuncG', 'feFuncB' and 'feFuncA' define the transfer functions.

Attribute definitions:

type = "identity | table | discrete | linear | gamma"

Indicates the type of component transfer function. The type of function determines the applicability of the other attributes.

  • For identity:
    C' = C
  • For table, the function is defined by linear interpolation into a lookup table by attribute tableValues, which provides a list of n+1 values (i.e., v0 to vn) in order to identify n interpolation ranges. Interpolations use the following formula:

    k/N <= C < (k+1)/N => C' = vk + (C - k/N)*N * (vk+1 - vk)

  • For discrete, the function is defined by the step function defined by attribute tableValues, which provides a list of n values (i.e., v0 to vn-1) in order to identify a step function consisting of n steps. The step function is defined by the following formula:

    k/N <= C < (k+1)/N => C' = vk

  • For linear, the function is defined by the following linear equation:

    C' = slope * C + intercept

  • For gamma, the function is defined by the following exponential function:

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

Animatable: yes.
tableValues = "(list of <number>s)"
When type="table", the list of <number>s v0,v1,...vn, separated by white space and/or a comma, which define the lookup table. An empty list results in an identity transfer function.
If the attribute is not specified, then the effect is as if an empty list were provided.
Animatable: yes.
slope = "<number>"
When type="linear", the slope of the linear function.
If the attribute is not specified, then the effect is as if a value of 1 were specified.
Animatable: yes.
intercept = "<number>"
When type="linear", the intercept of the linear function.
If the attribute is not specified, then the effect is as if a value of 0 were specified.
Animatable: yes.
amplitude = "<number>"
When type="gamma", the amplitude of the gamma function.
If the attribute is not specified, then the effect is as if a value of 1 were specified.
Animatable: yes.
exponent = "<number>"
When type="gamma", the exponent of the gamma function.
If the attribute is not specified, then the effect is as if a value of 1 were specified.
Animatable: yes.
offset = "<number>"
When type="gamma", the offset of the gamma function.
If the attribute is not specified, then the effect is as if a value of 0 were specified.
Animatable: yes.
Attributes defined elsewhere:
%stdAttrs;, %filter_primitive_attributes_with_in;.

Example feComponentTransfer shows examples of the four types of feComponentTransfer operations.

<?xml version="1.0"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20001102//EN" 
          "http://www.w3.org/TR/2000/CR-SVG-20001102/DTD/svg-20001102.dtd">
<svg width="8cm" height="4cm" viewBox="0 0 800 400">
  <title>Example feComponentTransfer - Examples of feComponentTransfer operations</title>
  <desc>Four text strings showing the effects of feComponentTransfer: 
        an identity function acting as a reference, 
        use of the feComponentTransfer table option,
        use of the feComponentTransfer linear option,
        and use of the feComponentTransfer gamma option.</desc>
  <defs>
    <linearGradient id="MyGradient" gradientUnits="userSpaceOnUse"
            x1="100" y1="0" x2="600" y2="0">
      <stop offset="0" style="stop-color:#ff0000"/>
      <stop offset=".33" style="stop-color:#00ff00"/>
      <stop offset=".67" style="stop-color:#0000ff"/>
      <stop offset="1" style="stop-color:#000000"/>
    </linearGradient>
    <filter id="Identity" filterUnits="objectBoundingBox" 
            x="0%" y="0%" width="100%" height="100%">
      <feComponentTransfer>
        <feFuncR type="identity"/>
        <feFuncG type="identity"/>
        <feFuncB type="identity"/>
        <feFuncA type="identity"/>
      </feComponentTransfer>
    </filter>
    <filter id="Table" filterUnits="objectBoundingBox" 
            x="0%" y="0%" width="100%" height="100%">
      <feComponentTransfer>
        <feFuncR type="table" tableValues="0 0 1 1"/>
        <feFuncG type="table" tableValues="1 1 0 0"/>
        <feFuncB type="table" tableValues="0 1 1 0"/>
      </feComponentTransfer>
    </filter>
    <filter id="Linear" filterUnits="objectBoundingBox" 
            x="0%" y="0%" width="100%" height="100%">
      <feComponentTransfer>
        <feFuncR type="linear" slope=".5" intercept=".25"/>
        <feFuncG type="linear" slope=".5" intercept="0"/>
        <feFuncB type="linear" slope=".5" intercept=".5"/>
      </feComponentTransfer>
    </filter>
    <filter id="Gamma" filterUnits="objectBoundingBox" 
            x="0%" y="0%" width="100%" height="100%">
      <feComponentTransfer>
        <feFuncR type="gamma" amplitude="2" exponent="5" offset="0"/>
        <feFuncG type="gamma" amplitude="2" exponent="3" offset="0"/>
        <feFuncB type="gamma" amplitude="2" exponent="1" offset="0"/>
      </feComponentTransfer>
    </filter>
  </defs>
  <rect style="fill:none; stroke:blue" 
        x="1" y="1" width="798" height="398"/>
  <g style="font-family:Verdana; font-size:75; 
            font-weight:bold; fill:url(#MyGradient)">
    <rect x="100" y="0" width="600" height="20" />
    <text x="100" y="90">Identity</text>
    <text x="100" y="190" style="filter:url(#Table)">TableLookup</text>
    <text x="100" y="290" style="filter:url(#Linear)">LinearFunc</text>
    <text x="100" y="390" style="filter:url(#Gamma)">GammaFunc</text>
  </g>
</svg>
Example feComponentTransfer
Example feComponentTransfer - Examples of feComponentTransfer operations

View this example as SVG (SVG-enabled browsers only)
 

15.12 Filter primitive 'feComposite'

This filter performs the combination of the two input images pixel-wise in image space using one of the Porter-Duff [PORTERDUFF] compositing operations: over, in, atop, out, xor. Additionally, a component-wise arithmetic operation (with the result clamped between [0..1]) can be applied.

The arithmetic operation is useful for combining the output from the 'feDiffuseLighting' and 'feSpecularLighting' filters with texture data. It is also useful for implementing dissolve. If the arithmetic operation is chosen, each result pixel is computed using the following formula:

result = k1*i1*i2 + k2*i1 + k3*i2 + k4

For these operations, the extent of the resulting image can be affected. In other words, even if two images do not overlap in image space, the extent for over will essentially include the union of the extents of the two input images.

<!ELEMENT feComposite (animate|set)* >
<!ATTLIST feComposite
  %stdAttrs;
  %filter_primitive_attributes_with_in;
  in2 CDATA #REQUIRED
  operator (over | in | out | atop | xor | arithmetic) "over"
  k1 %Number; #IMPLIED
  k2 %Number; #IMPLIED
  k3 %Number; #IMPLIED
  k4 %Number; #IMPLIED >

Attribute definitions:

operator = "over | in | out | atop | xor | arithmetic"
The compositing operation that is to be performed. All of the operator types except arithmetic match the correspond operation as described in [PORTERDUFF]. The arithmetic operator is described above.
Animatable: yes.
k1 = "<number>"
Only applicable if operator="arithmetic".
If the attribute is not specified, the effect is as if a value of "0" were specified.
Animatable: yes.
k2 = "<number>"
Only applicable if operator="arithmetic".
If the attribute is not specified, the effect is as if a value of "0" were specified.
Animatable: yes.
k3 = "<number>"
Only applicable if operator="arithmetic".
If the attribute is not specified, the effect is as if a value of "0" were specified.
Animatable: yes.
k4 = "<number>"
Only applicable if operator="arithmetic".
If the attribute is not specified, the effect is as if a value of "0" were specified.
Animatable: yes.
in2 = "(see in attribute)"
The second input image to the compositing operation. This attribute can take on the same values as the in attribute.
Animatable: yes.
Attributes defined elsewhere:
%stdAttrs;, %filter_primitive_attributes_with_in;.

Example feComposite shows examples of the six types of feComposite operations. It also shows two different techniques to using the BackgroundImage as part of the compositing operation.

The first two rows render bluish triangles into the background. A filter is applied which composites reddish triangles into the bluish triangles using one of the compositing operations. The result from compositing is drawn onto an opaque white temporary surface, and then that result is written to the canvas. (The opaque white temporary surface obliterates the original bluish triangle.)

The last two rows apply the same compositing operations of reddish triangles into bluish triangles. However, the compositing result is directly blended into the canvas (the opaque white temporary surface technique is not used). In some cases, the results are different than when a temporary opaque white surface is used. The original bluish triangle from the background shines through wherever the compositing operation results in completed transparent pixel. In other cases, the result from compositing is blended into the bluish triangle, resulting in a different final color value.

<?xml version="1.0"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20001102//EN" 
          "http://www.w3.org/TR/2000/CR-SVG-20001102/DTD/svg-20001102.dtd">
<svg width="11cm" height="6.5cm" viewBox="0 0 1100 650">
  <title>Example feComposite - Examples of feComposite operations</title>
  <desc>Four rows of six pairs of overlapping triangles depicting
        the six different feComposite operators under different
        opacity values and different clearing of the background.</desc>
	<defs>
    <desc>Define two sets of six filters for each of the six compositing operators.
          The first set wipes out the background image by flooding with opaque white.
          The second set does not wipe out the background, with the result
          that the background sometimes shines through and is other cases
          is blended into itself (i.e., "double-counting").</desc>
    <filter id="overFlood" filterUnits="objectBoundingBox" x="-5%" y="-5%" width="110%" height="110%">
      <feFlood style="flood-color:#ffffff; flood-opacity:1" result="flood"/>
      <feComposite in="SourceGraphic" in2="BackgroundImage" operator="over" result="comp"/>
      <feMerge> <feMergeNode in="flood"/> <feMergeNode in="comp"/> </feMerge>
    </filter>
    <filter id="inFlood" filterUnits="objectBoundingBox" x="-5%" y="-5%" width="110%" height="110%">
      <feFlood style="flood-color:#ffffff; flood-opacity:1" result="flood"/>
      <feComposite in="SourceGraphic" in2="BackgroundImage" operator="in" result="comp"/>
      <feMerge> <feMergeNode in="flood"/> <feMergeNode in="comp"/> </feMerge>
    </filter>
    <filter id="outFlood" filterUnits="objectBoundingBox" x="-5%" y="-5%" width="110%" height="110%">
      <feFlood style="flood-color:#ffffff; flood-opacity:1" result="flood"/>
      <feComposite in="SourceGraphic" in2="BackgroundImage" operator="out" result="comp"/>
      <feMerge> <feMergeNode in="flood"/> <feMergeNode in="comp"/> </feMerge>
    </filter>
    <filter id="atopFlood" filterUnits="objectBoundingBox" x="-5%" y="-5%" width="110%" height="110%">
      <feFlood style="flood-color:#ffffff; flood-opacity:1" result="flood"/>
      <feComposite in="SourceGraphic" in2="BackgroundImage" operator="atop" result="comp"/>
      <feMerge> <feMergeNode in="flood"/> <feMergeNode in="comp"/> </feMerge>
    </filter>
    <filter id="xorFlood" filterUnits="objectBoundingBox" x="-5%" y="-5%" width="110%" height="110%">
      <feFlood style="flood-color:#ffffff; flood-opacity:1" result="flood"/>
      <feComposite in="SourceGraphic" in2="BackgroundImage" operator="xor" result="comp"/>
      <feMerge> <feMergeNode in="flood"/> <feMergeNode in="comp"/> </feMerge>
    </filter>
    <filter id="arithmeticFlood" filterUnits="objectBoundingBox" 
            x="-5%" y="-5%" width="110%" height="110%">
      <feFlood style="flood-color:#ffffff; flood-opacity:1" result="flood"/>
      <feComposite in="SourceGraphic" in2="BackgroundImage" result="comp"
                   operator="arithmetic" k1=".5" k2=".5" k3=".5" k4=".5"/>
      <feMerge> <feMergeNode in="flood"/> <feMergeNode in="comp"/> </feMerge>
    </filter>
    <filter id="overNoFlood" filterUnits="objectBoundingBox" x="-5%" y="-5%" width="110%" height="110%">
      <feComposite in="SourceGraphic" in2="BackgroundImage" operator="over" result="comp"/>
    </filter>
    <filter id="inNoFlood" filterUnits="objectBoundingBox" x="-5%" y="-5%" width="110%" height="110%">
      <feComposite in="SourceGraphic" in2="BackgroundImage" operator="in" result="comp"/>
    </filter>
    <filter id="outNoFlood" filterUnits="objectBoundingBox" x="-5%" y="-5%" width="110%" height="110%">
      <feComposite in="SourceGraphic" in2="BackgroundImage" operator="out" result="comp"/>
    </filter>
    <filter id="atopNoFlood" filterUnits="objectBoundingBox" x="-5%" y="-5%" width="110%" height="110%">
      <feComposite in="SourceGraphic" in2="BackgroundImage" operator="atop" result="comp"/>
    </filter>
    <filter id="xorNoFlood" filterUnits="objectBoundingBox" x="-5%" y="-5%" width="110%" height="110%">
      <feComposite in="SourceGraphic" in2="BackgroundImage" operator="xor" result="comp"/>
    </filter>
    <filter id="arithmeticNoFlood" filterUnits="objectBoundingBox" 
            x="-5%" y="-5%" width="110%" height="110%">
      <feComposite in="SourceGraphic" in2="BackgroundImage" result="comp"
                   operator="arithmetic" k1=".5" k2=".5" k3=".5" k4=".5"/>
    </filter>
    <path id="Blue100" d="M 0 0 L 100 0 L 100 100 z" style="fill:#00ffff"/>
    <path id="Red100" d="M 0 0 L 0 100 L 100 0 z" style="fill:#ff00ff"/>
    <path id="Blue50" d="M 0 125 L 100 125 L 100 225 z" style="fill:#00ffff; fill-opacity:.5"/>
    <path id="Red50" d="M 0 125 L 0 225 L 100 125 z" style="fill:#ff00ff; fill-opacity:.5"/>
    <g id="TwoBlueTriangles">
      <use xlink:href="#Blue100"/>
      <use xlink:href="#Blue50"/>
    </g>
    <g id="BlueTriangles">
      <use transform="translate(275,25)" xlink:href="#TwoBlueTriangles"/>
      <use transform="translate(400,25)" xlink:href="#TwoBlueTriangles"/>
      <use transform="translate(525,25)" xlink:href="#TwoBlueTriangles"/>
      <use transform="translate(650,25)" xlink:href="#TwoBlueTriangles"/>
      <use transform="translate(775,25)" xlink:href="#TwoBlueTriangles"/>
      <use transform="translate(900,25)" xlink:href="#TwoBlueTriangles"/>
    </g>
  </defs>

  <rect style="fill:none; stroke:blue" x="1" y="1" width="1098" height="648"/>
  <g style="font-family:Verdana; font-size:40; shape-rendering:crispEdges">
    <desc>Render the examples using the filters that draw on top of
          an opaque white surface, thus obliterating the background.</desc>
    <g style="enable-background:new">
      <text x="15" y="75">opacity 1.0</text>
      <text x="15" y="115" style="font-size:27">(with feFlood)</text>
      <text x="15" y="200">opacity 0.5</text>
      <text x="15" y="240" style="font-size:27">(with feFlood)</text>
      <use xlink:href="#BlueTriangles"/>
      <g transform="translate(275,25)">
        <use  xlink:href="#Red100" style="filter:url(#overFlood)"/>
        <use  xlink:href="#Red50" style="filter:url(#overFlood)"/>
        <text x="5" y="275">over</text>
      </g>
      <g transform="translate(400,25)">
        <use  xlink:href="#Red100" style="filter:url(#inFlood)"/>
        <use  xlink:href="#Red50" style="filter:url(#inFlood)"/>
        <text x="35" y="275">in</text>
      </g>
      <g transform="translate(525,25)">
        <use  xlink:href="#Red100" style="filter:url(#outFlood)"/>
        <use  xlink:href="#Red50" style="filter:url(#outFlood)"/>
        <text x="15" y="275">out</text>
      </g>
      <g transform="translate(650,25)">
        <use  xlink:href="#Red100" style="filter:url(#atopFlood)"/>
        <use  xlink:href="#Red50" style="filter:url(#atopFlood)"/>
        <text x="10" y="275">atop</text>
      </g>
      <g transform="translate(775,25)">
        <use  xlink:href="#Red100" style="filter:url(#xorFlood)"/>
        <use  xlink:href="#Red50" style="filter:url(#xorFlood)"/>
        <text x="15" y="275">xor</text>
      </g>
      <g transform="translate(900,25)">
        <use  xlink:href="#Red100" style="filter:url(#arithmeticFlood)"/>
        <use  xlink:href="#Red50" style="filter:url(#arithmeticFlood)"/>
        <text x="-25" y="275">arithmetic</text>
      </g>
    </g>
    <g transform="translate(0,325)" style="enable-background:new">
    <desc>Render the examples using the filters that do not obliterate
          the background, thus sometimes causing the background to continue
          to appear in some cases, and in other cases the background
          image blends into itself ("double-counting").</desc>
      <text x="15" y="75">opacity 1.0</text>
      <text x="15" y="115" style="font-size:27">(without feFlood)</text>
      <text x="15" y="200">opacity 0.5</text>
      <text x="15" y="240" style="font-size:27">(without feFlood)</text>
      <use xlink:href="#BlueTriangles"/>
      <g transform="translate(275,25)">
        <use  xlink:href="#Red100" style="filter:url(#overNoFlood)"/>
        <use  xlink:href="#Red50" style="filter:url(#overNoFlood)"/>
        <text x="5" y="275">over</text>
      </g>
      <g transform="translate(400,25)">
        <use  xlink:href="#Red100" style="filter:url(#inNoFlood)"/>
        <use  xlink:href="#Red50" style="filter:url(#inNoFlood)"/>
        <text x="35" y="275">in</text>
      </g>
      <g transform="translate(525,25)">
        <use  xlink:href="#Red100" style="filter:url(#outNoFlood)"/>
        <use  xlink:href="#Red50" style="filter:url(#outNoFlood)"/>
        <text x="15" y="275">out</text>
      </g>
      <g transform="translate(650,25)">
        <use  xlink:href="#Red100" style="filter:url(#atopNoFlood)"/>
        <use  xlink:href="#Red50" style="filter:url(#atopNoFlood)"/>
        <text x="10" y="275">atop</text>
      </g>
      <g transform="translate(775,25)">
        <use  xlink:href="#Red100" style="filter:url(#xorNoFlood)"/>
        <use  xlink:href="#Red50" style="filter:url(#xorNoFlood)"/>
        <text x="15" y="275">xor</text>
      </g>
      <g transform="translate(900,25)">
        <use  xlink:href="#Red100" style="filter:url(#arithmeticNoFlood)"/>
        <use  xlink:href="#Red50" style="filter:url(#arithmeticNoFlood)"/>
        <text x="-25" y="275">arithmetic</text>
      </g>
    </g>
  </g>
</svg>
Example feComposite
Example feComposite - Examples of feComposite operations

View this example as SVG (SVG-enabled browsers only)
 

15.13 Filter primitive 'feConvolveMatrix'

feConvolveMatrix applies a matrix convolution filter effect. A convolution combines pixels in the input image with neighboring pixels to produce a resulting image. A wide variety of imaging operations can be achieved through convolutions, including blurring, edge detection, sharpening, embossing and beveling.

A matrix convolution is based on an n-by-m matrix (the convolution kernel) which describes how a given pixel value in the input image is combined with its neighboring pixel values to produce a resulting pixel value. Each result pixel is determined by applying the kernel matrix to the corresponding source pixel and its neighboring pixels.

To illustrate, suppose you have a input image which is 5 pixels by 5 pixels, whose color values are as follows:

    0  20  40 235 235
  100 120 140 235 235
  200 220 240 235 235
  225 225 255 255 255
  225 225 255 255 255

and you define a 3-by-3 convolution kernel as follows:

  1 2 3
  4 5 6
  7 8 9

Let's focus on the pixel at the second row and second column of the image (source pixel value is 120). Assuming the simplest case (where the input image's pixel grid aligns perfectly with the kernel's pixel grid) and assuming default values for attributes divisor, targetX and targetY, then resulting pixel value will be:

(1*  0 + 2* 20 + 3* 40 +
4*100 + 5*120 + 6*140 +
7*200 + 8*220 + 9*240) / (1+2+3+4+5+6+7+8+9)

Because they operate on pixels, matrix convolutions are inherently resolution-dependent. To make 'feConvolveMatrix produce resolution-independent results, an explicit value should be provided for either the filterRes attribute on the 'filter' element and/or attribute kernelUnitLength.

kernelUnitLength, in combination with the other attributes, defines an implicit pixel grid in the filter effects coordinate system (i.e., the coordinate system established by the filterUnits attribute). If the pixel grid established by kernelUnitLength does not align perfectly with the pixel grid established by attribute filterRes, then the input image will be temporarily resampled to align its pixels with kernelUnitLength. The convolution happens on the resampled image. After applying the convolution, the image is resampled back to its original resolution.

<!ELEMENT feConvolveMatrix (animate|set)* >
<!ATTLIST feConvolveMatrix
  %filter_primitive_attributes_with_in;
  order CDATA #REQUIRED
  kernelMatrix CDATA #REQUIRED
  divisor %Number; #IMPLIED
  bias %Number; #IMPLIED
  targetX %Integer; #IMPLIED
  targetY %Integer; #IMPLIED
  edgeMode (duplicate|wrap|none) "duplicate" 
  kernelUnitLength CDATA #IMPLIED 
  preserveAlpha %Boolean; #IMPLIED >

Attribute definitions:

order = "<orderX> [<orderY>]"
Indicates the number of cells in each dimension for kernelMatrix. The values provided must be <integer>s greater than zero. If two values are provided, the values are separated by space characters and/or a comma. <orderX> indicates the number of columns in the matrix. <orderY> indicates the number of rows in the matrix. If <orderY> is not provided, it defaults to <orderX>.
A typical value is order="3". It is recommended that only small values (e.g., 3) be used; higher values may result in very high CPU overhead and usually do not produce results that justify the impact on performance.
If the attribute is not specified, the effect is as if a value of "3" were specified.
Animatable: yes.
kernelMatrix = "<list of numbers>"
The list of <number>s that make up the kernel matrix for the convolution. Values are separated by space characters and/or a comma. The number of entries in the list must equal <orderX> times <orderY>.
Animatable: ye