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. In addition, the ability to apply filter effects to SVG graphics elements and container elements helps to maintain the semantic structure of the document, instead of resorting to images which aside from generally being a fixed resolution tend to obscure the original semantics of the elements they replace. This is especially true for effects applied to text.
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:

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 container 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 container elements with no content (e.g., an empty 'g' element), in which case the SourceGraphic or SourceAlpha consist of a transparent black rectangle that is the size of the filter effects region.
Sometimes filter primitives result in undefined pixels. For example, filter primitive 'feOffset' can shift an image down and to the right, leaving undefined pixels at the top and left. In these cases, the undefined pixels are set to transparent black.
The following shows an example of a filter effect.
Example filters01 - introducing filter effects.
<?xml version="1.0"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg width="7.5cm" height="5cm" viewBox="0 0 200 120"
xmlns="http://www.w3.org/2000/svg">
<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" filterUnits="userSpaceOnUse" x="0" y="0" width="200" height="120">
<feGaussianBlur in="SourceAlpha" stdDeviation="4" result="blur"/>
<feOffset in="blur" dx="4" dy="4" result="offsetBlur"/>
<feSpecularLighting in="blur" surfaceScale="5" specularConstant=".75"
specularExponent="20" lighting-color="#bbbbbb"
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" fill="#888888" stroke="blue" />
<g filter="url(#MyFilter)" >
<g>
<path 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 fill="#D90000"
d="M60,80 C30,80 30,40 60,40 L140,40 C170,40 170,80 140,80 z" />
<g fill="#FFFFFF" stroke="black" font-size="45" font-family="Verdana" >
<text x="52" y="76">SVG</text>
</g>
</g>
</g>
</svg>
![]() |
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" filterUnits="userSpaceOnUse" x="0" y="0" width="200" height="120">
<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=".75"
specularExponent="20" lighting-color="#bbbbbb"
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:
|
|
|
|
|||
|
|
|
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 %NumberOptionalNumber; #IMPLIED > |
Attribute definitions:
Properties inherit into the 'filter' element from its ancestors; properties do not inherit from the element referencing the 'filter' element.
'filter' elements are never rendered directly; their only usage is as something that can be referenced using the 'filter' property. The 'display' property does not apply to the 'filter' element; thus, 'filter' elements are not directly rendered even if the 'display' property is set to a value other than none, and 'filter' elements are available for referencing even when the 'display' property on the 'filter' element or any of its ancestors is set to none.
The description of the 'filter' property is as follows:
| Value: | <uri> | none | inherit |
| Initial: | none |
| Applies to: | container elements and graphics elements |
| Inherited: | no |
| Percentages: | N/A |
| Media: | visual |
| Animatable: | yes |
A 'filter' element can define a region on the canvas to 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:
x-pixels [y-pixels])
indicates the width and height of the intermediate images in pixels.
If not provided, then a reasonable default resolution appropriate for
the target device will be used. (For displays, an appropriate display
resolution, preferably the current display's pixel resolution, is the
default.
For printing, an appropriate common printer resolution, such as 400dpi,
is the default.)Note that both of the two possible value for filterUnits (i.e., objectBoundingBox and userSpaceOnUse) result in a filter region whose coordinate system has its X-axis and Y-axis each parallel to the X-axis and Y-axis, respectively, of the user coordinate system for the element to which the filter will be applied.
Sometimes implementers can achieve faster performance when the filter region can be mapped directly to device pixels; thus, for best performance on display devices, it is suggested that authors define their region such that SVG user agent can align the filter region pixel-for-pixel with the background. In particular, for best filter effects performance, avoid rotating or skewing the user coordinate system. Explicit values for attribute filterRes can either help or harm performance. If filterRes is smaller than the automatic (i.e., default) filter resolution, then filter effect might have faster performance (usually at the expense of quality). If filterRes is larger than the automatic (i.e., default) filter resolution, then filter effects performance will usually be slower.
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. This, for example, is why the defaults for the filter effects region are x="-10%" y="-10%" width="120%" height="120%".
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':
| 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 transparent black image shall be provided in response to the request.
The optional <x>,<y>,<width>,<height>
parameters on the new
value indicate the subregion of
the container element's
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.
Assume you have an element E in the document and that E has a series of ancestors A1 (its immediate parent), A2, etc. (Note: A0 is E.) Each ancestor Ai will have a corresponding temporary background image offscreen buffer BUFi. The contents of the background image available to a 'filter' referenced by E is defined as follows:
Example enable-background-01 illustrates the rules for background image processing.
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg width="13.5cm" height="2.7cm" viewBox="0 0 1350 270"
xmlns="http://www.w3.org/2000/svg">
<title>Example enable-background01</title>
<desc>This test case shows five pictures which illustrate the rules
for background image processing.</desc>
<defs>
<filter id="ShiftBGAndBlur"
filterUnits="userSpaceOnUse" x="0" y="0" width="1200" height="400">
<desc>
This filter discards the SourceGraphic, if any, and just produces
a result consisting of the BackgroundImage shifted down 125 units
and then blurred.
</desc>
<feOffset in="BackgroundImage" dx="0" dy="125" />
<feGaussianBlur stdDeviation="8" />
</filter>
<filter id="ShiftBGAndBlur_WithSourceGraphic"
filterUnits="userSpaceOnUse" x="0" y="0" width="1200" height="400">
<desc>
This filter takes the BackgroundImage, shifts it down 125 units, blurs it,
and then renders the SourceGraphic on top of the shifted/blurred background.
</desc>
<feOffset in="BackgroundImage" dx="0" dy="125" />
<feGaussianBlur stdDeviation="8" result="blur" />
<feMerge>
<feMergeNode in="blur"/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
</defs>
<g transform="translate(0,0)">
<desc>The first picture is our reference graphic without filters.</desc>
<rect x="25" y="25" width="100" height="100" fill="red"/>
<g opacity=".5">
<circle cx="125" cy="75" r="45" fill="green"/>
<polygon points="160,25 160,125 240,75" fill="blue"/>
</g>
<rect x="5" y="5" width="260" height="260" fill="none" stroke="blue"/>
</g>
<g enable-background="new" transform="translate(270,0)">
<desc>The second adds an empty 'g' element which invokes ShiftBGAndBlur.</desc>
<rect x="25" y="25" width="100" height="100" fill="red"/>
<g opacity=".5">
<circle cx="125" cy="75" r="45" fill="green"/>
<polygon points="160,25 160,125 240,75" fill="blue"/>
</g>
<g filter="url(#ShiftBGAndBlur)"/>
<rect x="5" y="5" width="260" height="260" fill="none" stroke="blue"/>
</g>
<g enable-background="new" transform="translate(540,0)">
<desc>The third invokes ShiftBGAndBlur on the inner group.</desc>
<rect x="25" y="25" width="100" height="100" fill="red"/>
<g filter="url(#ShiftBGAndBlur)" opacity=".5">
<circle cx="125" cy="75" r="45" fill="green"/>
<polygon points="160,25 160,125 240,75" fill="blue"/>
</g>
<rect x="5" y="5" width="260" height="260" fill="none" stroke="blue"/>
</g>
<g enable-background="new" transform="translate(810,0)">
<desc>The fourth invokes ShiftBGAndBlur on the triangle.</desc>
<rect x="25" y="25" width="100" height="100" fill="red"/>
<g opacity=".5">
<circle cx="125" cy="75" r="45" fill="green"/>
<polygon points="160,25 160,125 240,75" fill="blue"
filter="url(#ShiftBGAndBlur)"/>
</g>
<rect x="5" y="5" width="260" height="260" fill="none" stroke="blue"/>
</g>
<g enable-background="new" transform="translate(1080,0)">
<desc>The fifth invokes ShiftBGAndBlur_WithSourceGraphic on the triangle.</desc>
<rect x="25" y="25" width="100" height="100" fill="red"/>
<g opacity=".5">
<circle cx="125" cy="75" r="45" fill="green"/>
<polygon points="160,25 160,125 240,75" fill="blue"
filter="url(#ShiftBGAndBlur_WithSourceGraphic)"/>
</g>
<rect x="5" y="5" width="260" height="260" fill="none" stroke="blue"/>
</g>
</svg>
![]() |
View this example as SVG (SVG-enabled browsers only)
The example above contains five parts, described as follows:
This section describes the various filter primtives that can be assembled to achieve a particular filter effect.
Unless otherwise stated, all image filters operate on 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 primitive will have any negative color values or opacity values adjusted up to color/opacity of zero.
The color space in which a particular filter primitive performs its operations is determined by the value of property 'color-interpolation-filters' on the given filter primitive. A different property, 'color-interpolation' determines the color space for other color operations. Because these two properties have different initial values ('color-interpolation-filters' has an initial value of linearRGB whereas 'color-interpolation' has an initial value of sRGB), in some cases to achieve certain results (e.g., when coordinating gradient interpolation with a filtering operation) it will be necessary to explicitly set 'color-interpolation' to linearRGB or 'color-interpolation-filters' to sRGB on particular elements. Note that the examples below do not explicitly set either 'color-interpolation' or 'color-interpolation-filters', so the initial values for these properties apply to the examples.
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:
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 and thus represent values in the coordinate system established by attribute primitiveUnits on the 'filter' element.
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'), or one or more of the referenced nodes is a standard input (one of SourceGraphic, SourceAlpha, BackgroundImage, BackgroundAlpha, FillPaint or StrokePaint), or for 'feTile' (which is special because its principal function is to replicate the referenced node in X and Y and thereby produce a usually larger result), 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.
'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 in order to fill its own filter primitive subregion.
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.
<!ELEMENT feDistantLight (animate|set)* > <!ATTLIST feDistantLight %stdAttrs; azimuth %Number; #IMPLIED elevation %Number; #IMPLIED > |
Attribute definitions:
<!ELEMENT fePointLight (animate|set)* > <!ATTLIST fePointLight %stdAttrs; x %Number; #IMPLIED y %Number; #IMPLIED z %Number; #IMPLIED > |
Attribute definitions:
<!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:
The 'lighting-color' property defines the color of the light source for filter primitives 'feDiffuseLighting' and 'feSpecularLighting'.
| 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 |
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; %PresentationAttributes-FilterPrimitives; %filter_primitive_attributes_with_in; in2 CDATA #REQUIRED mode (normal | multiply | screen | darken | lighten) "normal" > |
Attribute definitions:
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) |
'normal' blend mode is equivalent to operator="over" on the 'feComposite' filter primitive, matches the blending method used by 'feMerge' and matches the simple alpha compositing technique used in SVG for all compositing outside of filter effects.
Example feBlend shows examples of the five blend modes.
<?xml version="1.0"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg width="5cm" height="5cm" viewBox="0 0 500 500"
xmlns="http://www.w3.org/2000/svg">
<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" 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>
<rect fill="none" stroke="blue"
x="1" y="1" width="498" height="498"/>
<g enable-background="new" >
<rect x="100" y="20" width="300" height="460" fill="url(#MyGradient)" />
<g font-family="Verdana" font-size="75" fill="#888888" fill-opacity=".6" >
<text x="50" y="90" filter="url(#Normal)" >Normal</text>
<text x="50" y="180" filter="url(#Multiply)" >Multiply</text>
<text x="50" y="270" filter="url(#Screen)" >Screen</text>
<text x="50" y="360" filter="url(#Darken)" >Darken</text>
<text x="50" y="450" filter="url(#Lighten)" >Lighten</text>
</g>
</g>
</svg>
![]() |
View this example as SVG (SVG-enabled browsers only)
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; %PresentationAttributes-FilterPrimitives; %filter_primitive_attributes_with_in; type (matrix | saturate | hueRotate | luminanceToAlpha) "matrix" values CDATA #IMPLIED > |
Attribute definitions:
type="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0"
| 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 |
| 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:
| a00 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.213 +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
| 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 |
Example feColorMatrix shows examples of the four types of feColorMatrix operations.
<?xml version="1.0"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg width="8cm" height="5cm" viewBox="0 0 800 500"
xmlns="http://www.w3.org/2000/svg">
<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" stop-color="#ff00ff" />
<stop offset=".33" stop-color="#88ff88" />
<stop offset=".67" stop-color="#2020ff" />
<stop offset="1" 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 fill="none" stroke="blue"
x="1" y="1" width="798" height="498"/>
<g 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" filter="url(#Matrix)" >Matrix</text>
<text x="100" y="290" filter="url(#Saturate40)" >Saturate</text>
<text x="100" y="390" filter="url(#HueRotate90)" >HueRotate</text>
<text x="100" y="490" filter="url(#LuminanceToAlpha)" >Luminance</text>
</g>
</svg>
![]() |
View this example as SVG (SVG-enabled browsers only)
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; %PresentationAttributes-FilterPrimitives; %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 attributes below apply to sub-elements 'feFuncR', 'feFuncG', 'feFuncB' and 'feFuncA' define the transfer functions.
Attribute definitions:
Indicates the type of component transfer function. The type of function determines the applicability of the other attributes.
C' = C
For a value C pick a k such that:
k/N <= C < (k+1)/N
The result C' is given by:
C' = vk + (C - k/N)*N * (vk+1 - vk)
For a value C pick a k such that:
k/N <= C < (k+1)/N
The result C' is given by:
C' = vk
Example feComponentTransfer shows examples of the four types of feComponentTransfer operations.
<?xml version="1.0"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg width="8cm" height="4cm" viewBox="0 0 800 400"
xmlns="http://www.w3.org/2000/svg">
<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" stop-color="#ff0000" />