4 septembre 2001

15 Les effets de filtre


Contenu


15.1 Introduction

Ce chapitre décrit le jeu des fonctions des effets de filtre déclaratifs de SVG, ceux-ci quand ils sont combinés avec les possibilités en 2D de SVG peuvent décrire la plupart des productions graphiques communes sur le Web, de telle façon que leur génération et leur modification côté client puisse être effectuées facilement. De plus, la possibilité d'appliquer des effets de filtre aux éléments graphiques et aux éléments conteneurs de SVG est favorable au maintien d'une structure sémantique du document, au lieu de faire appel à des images qui, non seulement, sont en général dans une résolution fixe, mais aussi qui tendent à obscurcir la sémantique générale des éléments qu'elles remplacent. Ceci est particulièrement vrai pour les effets appliqués au texte.

Un effet de filtre consiste en une succession d'opérations graphiques, appliquées sur un graphique source, dont le produit est un graphique modifié. Le résultat de l'effet de filtre est rendu sur l'appareil cible à la place du graphique source original. Voici une illustration du processus :

Image montrant un graphique source modifié par un effet de filtre

Voir cet exemple en SVG (seulement avec navigateur gérant SVG)
 

On définit un effet de filtre avec un élément 'filter'. Pour appliquer un effet de filtre sur un élément graphique ou un élément conteneur, on paramètre la propriété 'filter' de l'élément donné pour qu'ainsi elle appelle l'effet de filtre.

Chaque élément 'filter' contient un jeu de primitives de filtre comme enfants. Chaque primitive de filtre effectue une seule opération graphique fondamentale (par exemple, un flou ou un effet de lumière) sur une ou plusieurs entrées, donnant un résultat graphique. Comme la plupart des primitives de filtre représentent une certaine forme de traitement d'image, la sortie d'une primitive de filtre est généralement une seule image RGBA.

La source graphique originale ou le résultat d'une primitive de filtre peuvent être utilisés comme entrées pour une ou plusieurs autres primitives de filtre. La réutilisation de la source graphique est couramment employée. Par exemple, un simple filtre peut remplacer un graphique par deux, en ajoutant une copie noire du graphique source original, décalée pour créer un effet d'ombrage. En fait, ce sont deux couches de graphique, les deux ayant la même source graphique originale.

Appliquée aux éléments conteneurs, tel que l'élément 'g', la propriété 'filter' concerne le contenu du groupe comme un tout. Les enfants du groupe ne sont pas rendus directement à l'écran ; plutôt, les commandes graphiques nécessaires à leur rendu sont stockées temporairement. Typiquement, les commandes graphiques sont exécutées comme faisant partie du traitement de l'élément 'filter' appelé via les mots-clés SourceGraphic ou SourceAlpha. Les effets de filtre peuvent s'appliquer aux éléments conteneurs qui n'ont pas de contenu (par exemple, un élément 'g' vide), auquel cas les valeurs SourceGraphic ou SourceAlpha consistent en un rectangle noir transparent de la taille de la région de l'effet de filtre.

Les primitives de filtre résultent parfois en des pixels indéfinis. Par exemple, la primitive de filtre 'feOffset' peut déplacer une image vers le bas et vers la droite, laissant des pixels indéfinis en haut à gauche. Dans ces cas, les pixels indéfinis reçoivent une valeur de noir transparent.


15.2 Un exemple

Ce qui suit est un exemple d'effet de filtre.

L'exemple Filtres01 - introduction aux effets de filtre.

<?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>Exemple Filtres01 - introduction aux effets de filtre</title>
  <desc>Un exemple combinant plusieurs primitives de filtre
        pour obtenir un effet de lumière en 3D sur un graphique qui consiste
        de la chaîne "SVG" sur un ovale rempli en rouge entouré par
        un contour ovale rouge.</desc>
  <defs>
    <filter id="MonFiltre" filterUnits="userSpaceOnUse" x="0" y="0" width="200" height="120">
      <feGaussianBlur in="SourceAlpha" stdDeviation="4" result="flou"/>
      <feOffset in="flou" dx="4" dy="4" result="flouDecalage"/>
      <feSpecularLighting in="flou" surfaceScale="5" specularConstant=".75" 
                          specularExponent="20" lighting-color="#bbbbbb"  
                          result="speculaireSortie">
        <fePointLight x="-5000" y="-10000" z="20000"/>
      </feSpecularLighting>
      <feComposite in="speculaireSortie" in2="SourceAlpha" operator="in" result="speculaireSortie"/>
      <feComposite in="SourceGraphic" in2="speculaireSortie" operator="arithmetic" 
                   k1="0" k2="1" k3="1" k4="0" result="peintureEclairee"/>
      <feMerge>
        <feMergeNode in="flouDecalage"/>
        <feMergeNode in="peintureEclairee"/>
      </feMerge>
    </filter>
  </defs>
  <rect x="1" y="1" width="198" height="118" fill="#888888" stroke="blue" />
  <g filter="url(#MonFiltre)" >
	  <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>
Exemple Filtres01
Exemple Filtres01 - introduction aux effets de filtre

Voir cet exemple en SVG (seulement avec navigateur gérant SVG)
 

L'effet de filtre, utilisé dans l'exemple ci-dessus, est répété ici avec des numéros de référence dans la colonne de gauche devant chacune des six primitives de filtre :

 
 
1
2
3
 
 
 
 
4
5
 
6
 
 
 
 
<filter id="MonFiltre" filterUnits="userSpaceOnUse" x="0" y="0" width="200" height="120">
  <desc>Produces a 3D lighting effect.</desc>
  <feGaussianBlur in="SourceAlpha" stdDeviation="4" result="flou"/>
  <feOffset in="flou" dx="4" dy="4" result="flouDecalage"/>
  <feSpecularLighting in="flou" surfaceScale="5" specularConstant=".75" 
                      specularExponent="20" lighting-color="#bbbbbb" 
                      result="speculaireSortie">
    <fePointLight x="-5000" y="-10000" z="20000"/>
  </feSpecularLighting>
  <feComposite in="speculaireSortie" in2="SourceAlpha" operator="in" result="speculaireSortie"/>
  <feComposite in="SourceGraphic" in2="specOut" operator="arithmetic" 
               k1="0" k2="1" k3="1" k4="0" result="peintureEclairee"/>
  <feMerge>
    <feMergeNode in="flouDecalage"/>
    <feMergeNode in="peintureEclairee"/>
  </feMerge>
</filter>

Les images suivantes montrent les résultats intermédiaires obtenus à partir de chacun des éléments de filtre :

filters01 - graphique source original
Graphique source

 

filters01 - après filtre 1
Après primitive de filtre 1

 

filters01 - après filtre 2
Après primitive de filtre 2

 

filters01 - après filtre 3
Après primitive de filtre 3

  
   

filters01 - après filtre 4
Après primitive de filtre 4

 

filters01 - après filtre 5
Après primitive de filtre 5

 

filters01 - après filtre 6
Après primitive de filtre 6

  1. La primitive de filtre 'feGaussianBlur' reçoit en entrée la valeur de l'attribut SourceAlpha, qui est le canal alpha du graphique source. Le résultat est stocké dans un tampon temporaire nommé "flou". Remarquer que "flou" est utilisé comme entrée pour les deux primitives de filtre 2 et 3 ;
  2. La primitive de filtre 'feOffset' prend le tampon "flou", déplace le résultat dans une direction positive, à la fois dans x et y, puis crée un nouveau tampon nommé "flouDecalage". L'effet produit est celui d'un ombrage ;
  3. La primitive de filtre 'feSpecularLighting' utilise le tampon "blur" comme modèle pour une élévation de surface et génère un effet de lumière provenant d'une seule source. Le résultat est stocké dans le tampon "speculaireSortie" ;
  4. La primitive de filtre 'feComposite' applique un masque sur le résultat de la primitive de filtre 3 par le canal alpha de la source graphique originale, ainsi le résultat intermédiaire n'est pas plus grand que le graphique source original ;
  5. La primitive de filtre 'feComposite' compose le résultat de l'éclairage spéculaire avec le graphique source original ;
  6. La primitive de filtre 'feMerge' compose deux couches ensemble. La couche inférieure consiste du résultat de l'ombrage de la primitive de filtre 2. La couche supérieure consiste de l'éclairage spéculaire qui résulte de la primitive de filtre 5.

15.3 L'élément 'filter'

La description de l'élément 'filter' suit :

<!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 >

Définitions des attributs :

filterUnits = "userSpaceOnUse | objectBoundingBox"
Voir la section La région des effets de filtre.
primitiveUnits = "userSpaceOnUse | objectBoundingBox"
Spécifie le système de coordonnées pour les diverses valeurs de longueur des primitives de filtre et pour les attributs qui définissent la sous-région de primitive de filtre.
Pour une spécification primitiveUnits="userSpaceOnUse", toutes les valeurs de longueur des définitions de filtre représentent des valeurs dans le système de coordonnées utilisateur courant en vigueur au moment où l'élément 'filter' est appelé (i.e., le système de coordonnées utilisateur de l'élément qui appelle l'élément 'filter' via une propriété 'filter').
Pour une spécification primitiveUnits="objectBoundingBox", alors toutes les valeurs de longueur dans les définitions de filtre représentent des fractions ou des pourcentages de la boître de délimitation de l'élément appelant (voir la section Les unités de la boîte englobante de l'objet).
Si l'attribut primitiveUnits n'est pas spécifié, alors l'effet produit est comme si une valeur de userSpaceOnUse était spécifiée.
Animable : oui.
x = "<coordonnée>"
Voir la section La région des effets de filtre.
y = "<coordonnée>"
Voir la section La région des effets de filtre.
width = "<longueur>"
Voir la section La région des effets de filtre.
height = "<longueur>"
Voir la section La région des effets de filtre.
filterRes= "<nombre-nombre-optionnel>"
Voir la section La région des effets de filtre.
xlink:href = "<uri>"
Une référence d'URI vers un autre élément 'filter' dans le fragment de document SVG courant. Tous les attributs défins sur l'élément 'filter' appelé, qui ne sont pas définis sur cet élément, sont hérités par cet élément. Si cet élément n'a pas de nœuds définis et que l'élément appelé a des nœuds de filtre définis (éventuellement en raison de son propre attribut href), alors cet élément hérite des nœuds de filtre définis dans l'élément 'filter' appelé. L'héritage peut être indirect jusqu'à un niveau arbitraire ; ainsi, si l'élément 'filter' appelé hérite d'attributs ou de la spécification d'un nœud de filtre à partir de son propre attribut href, alors l'élément courant peut hériter de ces attributs ou de ces spécifications de nœud de filtre.
Animable : oui.
Attributs définis ailleurs :
%stdAttrs;, %langSpaceAttrs;, %xlinkRefAttrs; externalResourcesRequired, %PresentationAttributes-All;.

Les propriétés, dans l'élément 'filter', héritent des ancêtres de celui-ci ; les propriétés n'héritent pas de l'élément qui appelle l'élément 'filter'.

Les éléments 'filter' ne sont jamais rendus directement ; leur seule utilisation est comme quelque chose qu'on peut appeler avec la propriété 'filter'. La propriété 'display' ne s'applique pas aux éléments 'filter' ; ainsi, les éléments 'filter' ne sont pas rendus directement, même si la propriété 'display' a une valeur autre que none, et ils peuvent être appelés, même si la propriété 'display', sur l'élément 'filter' ou l'un de ses ancêtres, a une valeur de none.


15.4 La propriété 'filter'

La description de la propriété 'filter' est comme suit :

'filter'
Valeur :   <uri> | none | inherit vf.
Valeur initiale :   none
S'applique à :   ceux des éléments conteneurs et aux éléments graphiques
Héritée :   non
Pourcentages :   sans objet
Médias :   visuel
Animatable:   oui
<uri>
Une référence d'URI vers un élément 'filter' qui définit l'effet de filtre devant être appliqué à cet élément.
none
N'applique aucun effet de filtre à cet élément.

15.5 La région des effets de filtre

Un élément 'filter' peut définir une région du canevas sur laquelle un effet de filtre donné s'applique et peut fournir une résolution pour toute image intermédiaire en tons continus utilisée pour le traitement de toute primitive de filtre basée sur une trame de pixélisation. L'élément 'filter' admet les attributs suivants dont l'action se conjugue pour définir la région de l'effet de filtre :

Remarquer que les deux valeurs possibles pour l'attribut filterUnits (i.e., objectBoundingBox et userSpaceOnUse) conduisent à une région de filtre dont l'axe-x et l'axe-y du système de coordonnées sont parallèles, respectivement, aux axe-x et axe-y du système de coordonnées utilisateur de l'élément sur lequel le filtre sera appliqué.

Les implémenteurs peuvent parfois obtenir de meilleures performances quand on peut faire correspondre directement la région de filtre avec les pixels de l'appareil ; ainsi, pour la meilleure performance sur les appareils d'affichage, on suggère aux auteurs de définir leur région de telle manière que les agents utilisateurs SVG puissent aligner la région de filtre, pixel-à-pixel, sur l'arrière-plan. Notamment, pour la meilleure performance d'un effet de filtre, éviter de pivoter ou d'incliner le système de coordonnées utilisateur. Les valeurs explicites pour l'attribut filterRes peuvent soit favoriser, soit nuire aux performances. Si la valeur de filterRes est plus petite que la résolution du filtre automatique (i.e., par défaut), alors l'effet de filtre peut avoir une meilleure performance (généralement, au détriment de la qualité). Si la valeur de filterRes est plus grande que la résolution du filtre automatique (i.e., par défaut), alors la performance de l'effet de filtre sera généralement moindre.

Il est souvent nécessaire de donner un espacement environnant parce que l'effet de filtre peut agir sur des bits légèrement en-dehors de la boîte englobante resserrée d'un objet. Pour cela, on peut donner des valeurs en pourcentage négatives aux attributs x et y et des valeurs de pourcentage supérieures à "100%" aux attributs width et height. C'est la raison pour laquelle les valeurs par défaut de la région de l'effet du filtre sont x="-10%" y="-10%" width="120%" height="120%".

15.6 L'accès à l'image d'arrière-plan

Il existe deux pseudo-entrées d'image pour les effets de filtre, qui sont BackgroundImage et BackgroundAlpha, chacune représentant un cliché-image du canevas en-dessous de la région du filtre au moment où l'élément 'filter' est invoqué. L'entrée BackgroundImage représente à la fois les valeurs de couleur et du canal alpha du canevas (i.e., des valeurs de pixel RGBA), alors que BackgroundAlpha représente le seul canal alpha.

Les implémentations des agents utilisateurs SVG devront souvent maintenir des tampons supplémentaires de l'image d'arrière-plan pour gérer les pseudo-entrées d'image BackgroundImage et BackgroundAlpha. Certaines fois, les tampons d'image d'arrière-plan contiendront un copie en mémoire des opérations de peinture accumulées sur le canevas courant.

Comme les tampons d'image en mémoire peuvent consommer des ressources systèmes conséquentes, le contenu SVG doit indiquer explicitement à l'agent utilisateur que le document nécessite un accès à l'image d'arrière-plan avant de pouvoir utiliser les pseudo-entrées d'image BackgroundImage et BackgroundAlpha. C'est la propriété 'enable-background' qui active l'accès à l'image d'arrière-plan :

'enable-background'
Valeur :   accumulate | new [ <x> <y> <largeur> <hauteur> ] | inherit vf.
Valeur initiale :   accumulate
S'applique à :   ceux des éléments conteneurs
Héritée :   non
Pourcentages :   sans objet
Médias :   visuel
Animatable:   non

La propriété 'enable-background', qui ne s'applique qu'aux éléments conteneurs, gère l'accumulation de l'image d'arrière-plan.

Une valeur de new indique deux choses :

La signification de enable-background: accumulate (la valeur initiale/par défaut) dépend du contexte :

Si un effet de filtre spécifie l'une ou l'autre pseudo-entrée d'image BackgroundImage ou BackgroundAlpha et si aucun élément conteneur ancêtre n'a une valeur de propriété 'enable-background:new', alors la requête de l'image d'arrière-plan constitue techniquement une erreur. Le traitement continuera sans interruption (i.e., aucun message d'erreur) et une image noire transparente sera renvoyée en réponse à cette requête.

Les paramètres optionnels <x>,<y>,<largeur>,<hauteur> de la valeur new désigne la sous-région de l'espace utilisateur de l'élément conteneur sur laquelle l'accès à l'image d'arrière-plan est autorisé à survenir. Ces paramètres induisent éventuellement l'agent utilisateur à allouer des tampons d'image temporaires plus petits que ceux des valeurs par défaut, ces dernières pouvant demander à l'agent utilisateur SVG une allocation des tampons aussi grande que la zone de visualisation courante. Ainsi, les valeurs <x>,<y>,<largeur>,<hauteur> agissent comme un rectangle de rognage net sur le canevas de l'image d'arrière-plan. Une valeur négative pour <largeur>, ou <hauteur>, provoque une erreur (voir Le traitement des erreurs). Si on spécifie au moins une mais moins que quatre des valeurs <x>,<y>,<largeur> et <hauteur> ou si on ne spécifie aucune valeur pour <largeur> ou <hauteur>, les pseudo-entrées BackgroundImage et BackgroundAlpha sont traitées comme si le traitement de l'image d'arrière-plan n'était pas activé.

Supposons que l'on ait un élément E dans le document et que E ait une succession d'ancêtres A1 (son parent immédiat), A2, etc. (Remarque : A0 est E). Chaque ancêtre Ai aura un tampon d'image d'arrière-plan correspondant hors-écran TAMPONi. Le contenu de l'image d'arrière-plan qui est disponible pour un élément 'filter', appelé par E, est défini comme suit :

L'exemple enable-background01 illustre les règles pour le traitement d'une image d'arrière-plan.

<?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>Exemple enable-background01</title>
  <desc>Ce galop d'essais montre cinq dessins qui illustrent les règles
        pour le traitement d'une image d'arrière-plan.</desc>

  <defs>
    <filter id="ArrPlanDeplaceFlou" 
            filterUnits="userSpaceOnUse" x="0" y="0" width="1200" height="400">
      <desc>
        Ce filtre écarte la constante SourceGraphic, s'il y en a une, et ne produit que
        le déplacement de BackgroundImage de 125 unités vers le bas
        puis applique un flou.
      </desc>
      <feOffset in="BackgroundImage" dx="0" dy="125" />
      <feGaussianBlur stdDeviation="8" />
    </filter>
    <filter id="ArrPlanDeplaceFlou_sansSourceGraphic" 
            filterUnits="userSpaceOnUse" x="0" y="0" width="1200" height="400">
      <desc>
        Ce filtre prend BackgroundImage, le déplace de 125 unités vers le bas, applique un flou
        puis rend SourceGraphic par-dessus l'arrière-plan déplacé et flou.
      </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>La première image est le graphique de référence sans filtre.</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>La deuxième ajoute un élément 'g' vide qui invoque ArrPlanDeplaceFlou.</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(#ArrPlanDeplaceFlou)"/>
    <rect x="5" y="5" width="260" height="260" fill="none" stroke="blue"/>
  </g>

  <g enable-background="new" transform="translate(540,0)">
    <desc>La troisième invoque ArrPlanDeplaceFlou sur le groupe interne.</desc>
    <rect x="25" y="25" width="100" height="100" fill="red"/>
    <g filter="url(#ArrPlanDeplaceFlou)" 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>Le quatrième invoque ArrPlanDeplaceFlou sur le 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(#ArrPlanDeplaceFlou)"/>
    </g>
    <rect x="5" y="5" width="260" height="260" fill="none" stroke="blue"/>
  </g>

  <g enable-background="new" transform="translate(1080,0)">
    <desc>Le cinquième invoque ArrPlanDeplaceFlou_sansSourceGraphic sur le 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(#ArrPlanDeplaceFlou_sansSourceGraphic)"/>
    </g>
    <rect x="5" y="5" width="260" height="260" fill="none" stroke="blue"/>
  </g>
</svg>
Exemple enable-background01
Exemple enable-background-01 - illustration des règles de traitement de l'image d'arrière-plan

Voir cet exemple en SVG (seulement avec navigateur gérant SVG)
 

L'exemple ci-dessus se décompose en cinq parties, décrites comme suit :

  1. Le premier jeu représente le graphique de référence. Celui-ci consiste en un rectangle rouge suivi d'un élément 'g' transparent à 50%. Dans l'élément 'g' se trouvent un cercle vert qui recouvre partiellement le rectangle et un triangle bleu qui recouvre partiellement le cercle. Les trois objets sont ensuite entourés par un rectangle avec un liseré bleu mince. Aucun filtre n'est appliqué à ce graphique de référence ;
  2. Le deuxième jeu active le traitement de l'image d'arrière-plan et ajoute un élément 'g' vide qui invoque le filtre ArrPlanDeplaceFlou. Ce filtre prend en entrée l'image d'arrière-plan cumulée courante (i.e., le graphique de référence en entier), la déplace hors-écran vers le bas, lui applique un flou puis transcrit le résultat sur canevas. Remarquer que le hors-écran pour le filtre est initialisé au noir transparent, ce qui permet au rectangle, au cercle et au triangle déjà rendus de transparaître après que le filtre a rendu son propre résultat sur le canevas ;
  3. Le troisième jeu active le traitement de l'image d'arrière-plan et, autrement, invoque le filtre ArrPlanDeplaceFlou sur l'élément 'g' interne. L'arrière-plan cumulé, au moment de l'application du filtre, ne contient que le rectangle rouge. Ceci du fait que les enfants de l'élément 'g' interne (i.e., le cercle et le triangle) ne font pas partie de l'arrière-plan de cet élément 'g' interne et, comme le filtre ArrPlanDeplaceFlou ignore la valeur SourceGraphic, les enfants de l'élément 'g' interne n'apparaissent pas dans le résultat ;
  4. Le quatrième jeu active le traitement de l'image d'arrière-plan et invoque le filtre ArrPlanDeplaceFlou sur l'élément 'polygon' qui dessine le triangle. L'arrière-plan cumulé, au moment de l'application du filtre, contient le rectangle rouge plus le cercle vert qui ignorent l'effet de la propriété 'opacity' sur l'élément 'g'. (Remarquer que le cercle vert flou, en bas, ne laisse pas transparaître le rectangle rouge à sa gauche. Ceci est dû à l'ignorance de la propriété 'opacity'). Comme le triangle lui-même ne fait pas partie de l'arrière-plan cumulé et comme le filtre ArrPlanDeplaceFlou ignore la valeur SourceGraphic, le triangle n'apparaît pas dans le résultat ;
  5. Le cinquième jeu reproduit le quatrièem, sauf que c'est le filtre ArrPlanDeplaceFlou_sansSourceGraphic qui est invoqué, au lieu de ArrPlanDeplaceFlou. Le filtre ArrPlanDeplaceFlou_sansSourceGraphic réalise le même effet que ArrPlanDeplaceFlou, mais rend SourceGraphic par-dessus l'image d'arrière-plan déplacée et floue. Dans ce cas, SourceGraphic représente le triangle bleu ; ainsi, le résultat est identique à celui du quatrième jeu, à la différence que le triangle bleu apparaît maintenant.

15.7 Aperçu sur les primitives de filtre

15.7.1 Aperçu

Cette section décrit les diverses primitives de filtre pouvant être assemblées pour obtenir un effet de filtre particulier.

À moins d'être précisé autrement, tous les filtres d'image opèrent sur des échantillons RGBA prémultipliés. Les filtres dont l'action est plus naturelle sur des données non prémultipliées (feColorMatrix et feComponentTransfer) déferont temporairement puis referont une prémultiplication comme spécifié. Toutes les opérations d'effet de filtre pixélisé prennent en entrée 1 à N images RGBA, des attributs supplémentaires comme paramètres et produisent en sortie une seule image RGBA.

Le résultat RGBA de chaque primitive de filtre sera ramené dans les plages de valeurs de couleur et de valeurs d'opacité permises. Ainsi, par exemple, les valeurs de couleur ou d'opacité négatives seront ajustées sur une valeur de couleur/opacité de zéro dans le résultat d'une primitive de filtre donnée.

L'espace de couleur, dans lequel une primitive de filtre particulière opère, est déterminé par la valeur de la propriété 'color-interpolation-filters' sur la primitive de filtre en question. Une autre propriété 'color-interpolation' détermine l'espace de couleur pour d'autres opérations de couleur. Ces deux propriétés ayant des valeurs initiales différentes ('color-interpolation-filters' a une valeur initiale de linearRGB, alors que 'color-interpolation' a une valeur initiale de sRGB), dans certains cas où il faut obtenir des résultats particuliers (par exemple, pour la coordination d'une interpolation de dégradé et d'une opération de filtre), il sera nécessaire de spécifier explicitement la propriété 'color-interpolation' à linearRGB, ou la propriété 'color-interpolation-filters' à sRGB, sur des éléments particuliers. Remarquer que les exemples ci-dessous ne spécifient aucune valeur explicite pour l'une ou l'autre propriétés 'color-interpolation' et 'color-interpolation-filters', c'est ainsi leur valeur initiale qui s'applique.

15.7.2 Les attributs communs

Les attributs suivants sont disponibles pour toutes les primitives de filtre :

<!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">

Définitions des attributs :

x = "<coordonnée>"
La coordonnée x minimum, pour la sous-région où le calcul et le rendu de la primitive de filtre donnée se restreignent. Voir la section La sous-région d'une primitive de filtre.
Animable : oui.
y = "<coordonnée>"
La coordonnée y minimum, pour la sous-région où le calcul et le rendu de la primitive de filtre donnée se restreignent. Voir la section La sous-région d'une primitive de filtre.
Animable : oui.
width = "<longueur>"
La largeur de la sous-région où le calcul et le rendu de la primitive de filtre donnée se restreignent. Voir la section La sous-région d'une primitive de filtre.
Une valeur négative provoque une erreur (voir Le traitement des erreurs). Une valeur de zéro désactive l'effet de la primitive de filtre donnée (i.e., ceci résulte en une image noire transparente).
Animable : oui.
height = "<longueur>"
La hauteur de la sous-région où le calcul et le rendu de la primitive de filtre donnée se restreignent. Voir la sectionLa sous-région d'une primitive de filtre.
Une valeur négative provoque une erreur (voir Le traitement des erreurs). Une valeur de zéro désactive l'effet de la primitive de filtre donnée (i.e., ceci résulte en une image noire transparente).
Animable : oui.
result = "<primitive-filtre-référence>"
Le nom assigné à cette primitive de filtre. Quand il est fourni, alors les graphiques issus du traitement de cette primitive de filtre peuvent être appelés par un attribut in sur une primitive de filtre subséquente dans le même élément 'filter'. Si aucune valeur n'est fournie, la sortie ne sera disponible qu'en réutilisation comme entrée implicite pour la primitive de filtre suivante, si cette dernière n'a aucune valeur pour son attribut in.
Remarquer que le type <primitive-filtre-référence> n'est pas un ID XML ; une valeur <primitive-filtre-référence> n'est plutôt significative que dans élément 'filter' donné et n'a ainsi qu'une portée locale. La même valeur <primitive-filtre-référence> peut apparaître plusieurs fois dans un même élément 'filter'. Quand elle est appelée, la valeur <primitive-filtre-référence> utilisera la primitive de filtre précédente la plus proche pour l'attribut result donné.
Animable : oui.
in = "SourceGraphic | SourceAlpha | BackgroundImage | BackgroundAlpha | FillPaint | StrokePaint | <primitive-filtre-référence>"
Identifie une entrée pour la primitive de filtre donnée. La valeur peut être l'un ou l'autre des six mots-clés ou une chaîne qui correspond à la valeur d'un attribut result précédent dans le même élément 'filter'. Si aucune valeur n'est fournie et si c'est la première primitive de filtre, alors cette primitive de filtre utilisera la valeur SourceGraphic comme entrée. Si aucune valeur n'est fournie et si c'est une primitive de filtre subséquente, alors cette primitive de filtre utilisera le résultat de la primitive de filtre précédente comme entrée.

Si la valeur de l'attribut result apparaît plusieurs fois dans un élément 'filter' donné, alors un appel de ce résultat utilisera la primitive de filtre précédente la plus proche ayant la valeur donnée pour l'attribut result. Un appel de résultat descendant provoque une erreur.

Définitions des six mots-clés :
SourceGraphic
Ce mot-clé représente les éléments graphiques qui formaient l'entrée originale de l'élément 'filter'. Pour les primitives d'effets de filtre pixélisés, les éléments graphiques seront pixélisés en une trame RGBA initialement claire dans l'espace de l'image. Les pixels qui n'auront pas été touchés par le graphique original resteront clairs. L'image est spécifiée pour être rendue en pixels RGBA linéaires. Le canal alpha de cette image capture tout anti-crénelage spécifié par SVG. (Comme la trame est linéaire, le canal alpha de cette image représentera le pourcentage de couverture exact de chaque pixel).
SourceAlpha
Ce mot-clé représente les éléments graphiques qui formaient l'entrée originale de l'élément 'filter'. La valeur SourceAlpha suit toutes les mêmes règles que SourceGraphic, sauf que seul le canal alpha est utilisé. L'entrée est une image RGBA, consistant en valeurs de couleur noires pour les canaux RGB, mais dont le canal alpha est le même que SourceGraphic. Quand cette option est utilisée, alors certaines implémentations peuvent devoir pixéliser les éléments graphiques pour l'extraction du canal alpha.
BackgroundImage
Ce mot-clé représente un cliché-image du canevas en-dessous de la région du filtre au moment où l'élément 'filter' est invoqué. Voir la section L'accès à l'image d'arrière-plan.
BackgroundAlpha
Même chose que pour BackgroundImage, sauf que seul le canal alpha est utilisé. Voir SourceAlpha et la section L'accès à l'image d'arrière-plan.
FillPaint
Ce mot-clé représente la valeur de la propriété 'fill' sur l'élément cible pour l'effet de filtre. L'image FillPaint s'étend conceptuellement à l'infini. Fréquemment, cette image est partout opaque, mais ceci peut ne plus être le cas si la « peinture » elle-même a une valeur alpha, comme c'est le cas pour un dégradé, ou un motif, qui lui-même comprend des parties transparentes ou semi-transparentes.
StrokePaint
Ce mot-clé représente la valeur de la propriété 'stroke' sur l'élément cible pour l'effet de filtre. L'image StrokePaint s'étend conceptuellement à l'infini. Fréquemment, cette image est partout opaque, mais ceci peut ne plus être le cas si la « peinture » elle-même a une valeur alpha, comme c'est le cas pour un dégradé, ou un motif, qui lui-même comprend des parties transparentes ou semi-transparentes.
Animable : oui.

15.7.3 La sous-région d'une primitive de filtre

Toutes les primitives de filtre ont des attributs x, y, width et height qui identifient une sous-région où le calcul et le rendu de la primitive de filtre donnée se restreignent. Ces attributs sont définis en fonction des mêmes règles que pour les attributs de coordonnée et de longueur des autres primitives de filtre, ainsi ils représentent des valeurs dans le système de coordonnées établit par l'attribut primitiveUnits sur l'élément 'filter'.

Les attributs x, y, width et height se rabattent par défaut à l'union (i.e., la boîte englobante de logement la plus serrée) des sous-régions définies pour tous les nœuds appelés. S'il n'y a pas de nœuds appelés (par exemple, pour les primitives 'feImage' ou 'feTurbulence') ou si l'un ou plusieurs des nœuds appelés est une entrée standard (parmi SourceGraphic, SourceAlpha, BackgroundImage, BackgroundAlpha, FillPaint ou StrokePaint) ou si c'est la primitive 'feTile' (qui est particulière en ce sens que sa fonction principale consiste à répliquer le nœud appelé sur X et Y, produisant ainsi un résultat généralement plus grand), la sous-région par défaut est 0%,0%,100%,100%, où les pourcentages se rapportent aux dimensions de la région de filtre.

Les attributs x, y, width et height agissent comme un rectangle de rognage net.

Toutes les images intermédiaires hors-écran sont définies pour ne pas excéder l'intersection désignée par x, y, width et height avec la région de filtre. La région de filtre et toutes les sous-région x, y, width, height doivent être réglées de façon à ce que toutes les images hors-écran soient suffisamment grande pour accomoder tout pixel qui pourrait se trouver à l'intersection, même partiellement, soit de la région de filtre, soit des sous-régions x,y,width,height.

La primitive 'feTile' référence une primitive de filtre précédente, puis assemble les carreaux de mosaïque en fonction des valeurs des attributs x, y, width et height de la primitive de filtre appelée pour remplir sa propre sous-région de primitive de filtre.

15.8 Les éléments et les propriétés de source lumineuse

15.8.1 Introduction

Les sections suivantes définissent les élément qui décrivent une source lumineuse, à savoir 'feDistantLight', 'fePointLight' et 'feSpotLight', et la propriété 'lighting-color', qui définit la couleur de la lumière.

15.8.2 La source lumineuse 'feDistantLight'

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

Définitions des attributs :

azimuth = "<nombre>"
La direction de l'angle de la source lumineuse sur le plan XY, en degrés.
Si l'attribut n'est pas spécifié, l'effet produit est comme si une valeur de 0 était spécifiée.
Animable : oui.
elevation = "<nombre>"
La direction de l'ange de la source lumineuse sur le plan YZ, en degrés.
Si l'attribut n'est pas spécifié, l'effet produit est comme si une valeur de 0 était spécifiée.
Animable : oui.
Attributs définis ailleurs :
%stdAttrs;.

15.8.3 La source lumineuse 'fePointLight'

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

Définitions des attributs :

x = "<nombre>"
La localisation X de la source lumineuse dans le système de coordonnées établi par l'attribut primitiveUnits sur l'élément 'filter'.
Si l'attribut n'est pas spécifié, l'effet produit est comme si une valeur de 0 était spécifiée.
Animable : oui.
y = "<nombre>"
La localisation Y de la source lumineuse dans le système de coordonnées établi par l'attribut primitiveUnits sur l'élément 'filter'.
Si l'attribut n'est pas spécifié, l'effet produit est comme si une valeur de 0 était spécifiée.
Animable : oui.
z = "<nombre>"
La localisation Z de la source lumineuse dans le système de coordonnées établi par l'attribut primitiveUnits sur l'élément 'filter', en supposant que, dans le système de coordonnées initial, l'axe-z positif se dirige vers la personne qui regarde le contenu et en supposant qu'une unité le long de l'axe-z soit égale à une unité selon l'axe-x ou l'axe-y.
Si l'attribut n'est pas spécifié, l'effet produit est comme si une valeur de 0 était spécifiée.
Animable : oui.
Attributs définis ailleurs :
%stdAttrs;.

15.8.4 La source lumineuse'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 >

Définitions des attributs :

x = "<nombre>"
La localisation X de la source lumineuse dans le système de coordonnées établi par l'attribut primitiveUnits sur l'élément 'filter'.
Si l'attribut n'est pas spécifié, l'effet produit est comme si une valeur de 0 était spécifiée.
Animable : oui.
y = "<nombre>"
La localisation Y de la source lumineuse dans le système de coordonnées établi par l'attribut primitiveUnits sur l'élément 'filter'.
Si l'attribut n'est pas spécifié, l'effet produit est comme si une valeur de 0 était spécifiée.
Animable : oui.
z = "<nombre>"
La localisation Z de la source lumineuse dans le système de coordonnées établi par l'attribut primitiveUnits sur l'élément 'filter', en supposant que, dans le système de coordonnées initial, l'axe-z positif se dirige vers la personne qui regarde le contenu et en supposant qu'une unité le long de l'axe-z soit égale à une unité selon l'axe-x ou l'axe-y.
Si l'attribut n'est pas spécifié, l'effet produit est comme si une valeur de 0 était spécifiée.
Animable : oui.
pointsAtX = "<nombre>"
La localisation X de la source lumineuse, dans le système de coordonnées établi par l'attribut primitiveUnits sur l'élément 'filter', du point vers lequel la source lumineuse se dirige.
Si l'attribut n'est pas spécifié, l'effet produit est comme si une valeur de 0 était spécifiée.
Animable : oui.
pointsAtY = "<nombre>"
La localisation Y de la source lumineuse, dans le système de coordonnées établi par l'attribut primitiveUnits sur l'élément 'filter', du point vers lequel la source lumineuse se dirige.
Si l'attribut n'est pas spécifié, l'effet produit est comme si une valeur de 0 était spécifiée.
Animable : oui.
pointsAtZ = "<nombre>"
La localisation Z du point vers lequel la source lumineuse se dirige, en supposant que, dans le système de coordonnées initial, l'axe-z positif se dirige vers la personne qui regarde le contenu et en supposant qu'une unité le long de l'axe-z soit égale à une unité selon l'axe-x ou l'axe-y.
Si l'attribut n'est pas spécifié, l'effet produit est comme si une valeur de 0 était spécifiée.
Animable : oui.
specularExponent = "<nombre>"
Une valeur d'exposant qui contrôle le foyer de la source lumineuse.
Si l'attribut n'est pas spécifié, l'effet produit est comme si une valeur de 1 était spécifiée.
Animable : oui.
limitingConeAngle = "<nombre>"
Un cône de délimitation qui contraint la région sur laquelle la lumière se projette. Aucune lumière n'est projetée en-dehors du cône. La valeur limitingConeAngle représente l'angle entre l'axe du faisceau de lumière (i.e., l'axe allant de la source lumineuse au point sur lequelle elle pointe) et le cone du faisceau de lumière. Les agents utilisateurs devraient appliquer des techniques de lissage, comme l'anti-crénelage, aux limites du cône.
Si aucune valeur n'est spécifiée, alors aucun cône de délimitation n'est appliqué.
Animable : oui.
Attributs définis ailleurs :
%stdAttrs;.

15.8.5 La propriété 'lighting-color'

La propriété 'lighting-color' définit la couleur de la source lumineuse pour les primitives de filtre 'feDiffuseLighting' et 'feSpecularLighting'.

'lighting-color'
Valeur :   currentColor |
<couleur> [icc-color(<nom>[,<valeur-couleur-icc>]*)] |
inherit vf.
Valeur initiale :   white
S'applique à :   ceux des éléments 'feDiffuseLighting' et 'feSpecularLighting'
Héritée :   non
Pourcentages :   sans objet
Médias :   visuel
Animatable:   oui

15.9 La primitive de filtre 'feBlend'

Ce filtre compose deux objets à l'aide de modes de mélange couramment employés par les logiciels d'imagerie. Il effectue une combinaison au pixel de deux images en entrée.

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

Définitions des attributs :

mode = "normal | multiply | screen | darken | lighten"
Un des modes de mélange d'images (voir le tableau ci-dessous). La valeur par défaut est "normal".
Animable : oui.
in2 = "(voir l'attribut in)"
La seconde image en entrée de l'opération de mélange. Cet attribut prend les mêmes valeurs que l'attribut in.
Animable : oui.
Attributs définis ailleurs :
%stdAttrs;, %filter_primitive_attributes_with_in;, %PresentationAttributes-FilterPrimitives;.

Pour tous les modes de feBlend, l'opacité résultante se calcule comme suit :

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

Voici les définitions qui s'appliquent aux formules de composition ci-dessous :

cr = Couleur résultante (RGB) - prémultipliée 
qa = Valeur d'opacité à un pixel donné pour l'image A
qb = Valeur d'opacité à un pixel donné pour l'image B 
ca = Couleur (RGB) à un pixel donné pour l'image A - prémultipliée 
cb = Couleur (RGB) à un pixel donné pour l'image B - prémultipliée 

Le tableau suivant donne la liste des modes de mélange d'images disponibles :

Mode de mélange d'images Formule pour le calcul de la couleur résultante
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)

Le mode de mélange 'normal' est équivalent à la spécification operator="over" sur la primitive de filtre 'feComposite', correspond à la méthode de mélange utilisée par l'élément 'feMerge' et correspond à la technique de composition alpha simple utilisée dans SVG pour toute composition en-dehors des effets de filtre.

L'exemple feBlend illustre les cinq modes de mélange.

<?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>Exemple feBlend - les modes de mélange feBlend</title>
  <desc>Cinq chaînes textuelles mélangées à un dégradé,
        une chaîne pour chacun des modes de mélange de feBlend.</desc>
  <defs>
    <linearGradient id="MonDegrade" 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(#MonDegrade)" />
    <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>
Exemple feBlend
Exemple feBlend - les modes de feBlend

Voir cet exemple en SVG (seulement avec navigateur gérant SVG)
 

15.10 La primitive de filtre 'feColorMatrix'

Ce filtre applique une matrice de 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 |

sur les valeurs de couleur et alpha RGBA de chaque pixel du graphique en entrée pour produire un résultat avec un nouveau jeu de valeurs de couleur et alpha RGBA.

Les calculs s'effectuent sur des valeurs de couleurs non prémultipliées. Si le graphique en entrée consiste en valeurs de couleur prémultipliées, celles-ci sont automatiquement converties en valeurs non prémultipliées pour cette opération.

Ces matrices effectuent souvent une correspondance à l'identique dans le canal alpha. Auquel cas, une implémentation peut éviter le coûteux défaire et refaire de la prémultiplication en donnant à tous les pixels une valeur 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 >

Définitions des attributs :

type = "matrix | saturate | hueRotate | luminanceToAlpha"
Indique le type d'opération de matrice. Le mot-clé matrix signifie la fourniture d'une matrice de valeurs 5x4 complète. Les autres mots-clés représentent des raccourcis pratiques qui permettent les opérations de couleur couramment employées, sans devoir spécifier une matrice complète.
Animable : oui.
values= "liste de valeurs <nombre>"
Le contenu de l'attribut values dépend de la valeur de l'attribut type :
  • Pour type="matrix", l'attribut values admet une liste de 20 valeurs de matrice (a00 a01 a02 a03 a04 a10 a11 ... a34), séparées par des blancs et/ou des virgules. Par exemple, la matrice identité pourrait s'exprimer ainsi :
    type="matrix" 
    values="1 0 0 0 0  0 1 0 0 0  0 0 1 0 0  0 0 0 1 0"
    
  • Pour type="saturate", l'attribut values admet une seule valeur de nombre réel (de 0 à 1). Une opération saturate équivaut à la matrice suivante :
    | 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 |
    
  • Pour type="hueRotate", l'attribut values admet une seule valeur de nombre réel (degrés). Une opération hueRotate équivaut à la matrice suivante :
    | 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 |
    
    dans laquelle les termes a00, a01, etc. se calcule comme suit :
    | 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(valeur hueRotate) *  [-0.213 +0.285 -0.072] +
                             [-0.213 -0.715 +0.928]
    
                             [-0.213 -0.715+0.928]
    sin(valeur hueRotate) *  [+0.143 +0.140-0.283]
                             [-0.787 +0.715+0.072]
    
    Ainsi, le terme supérieur gauche de la matrice hueRotate revient à :
    .213 + cos(valeur hueRotate)*.787 - sin(valeur hueRotate)*.213
    
  • Pour type="luminanceToAlpha", l'attribut values ne s'applique pas. Une opération luminanceToAlpha équivaut à la matrice suivante :
       | 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 |
    
Si l'attribut n'est pas spécifié, alors le comportement par défaut dépend de la valeur de l'attribut type. Pour type="matrix", alors, par défaut, l'attribut est la matrice identité. Pour type="saturate", alors la valeur par défaut de l'attribut est 1, ce qui revient à la matrice identité. Pour type="hueRotate", alors la valeur par défaut de l'attribut est 0, ce qui revient à la matrice identité.
Animable : oui.
Attributs définis ailleurs :
%stdAttrs;, %filter_primitive_attributes_with_in;, %PresentationAttributes-FilterPrimitives;.

L'exemple feColorMatrix illustre les quatre types d'opérations de feColorMatrix.

<?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>Exemple feColorMatrix - les opérations de feColorMatrix</title>
  <desc>Cinq chaînes textuelles montre les effets de feColorMatrix: 
        - une chaîne textuelle non filtrée qui est la référence ; 
        - l'option matrix de feColorMatrix pour une conversion en niveaux de gris ;
        - l'option saturate de feColorMatrix ;
        - l'option hueRotate de feColorMatrix ;
        - l'option luminanceToAlpha de feColorMatrix.</desc>
  <defs>
    <linearGradient id="MonDegrade" 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%"/> « errata 2002-11-15 »
    </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(#MonDegrade)" >
    <rect x="100" y="0" width="500" height="20" />
    <text x="100" y="90">Pas de filtre</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>
Exemple feColorMatrix
Exemple feColorMatrix - Exemples d'opérations feColorMatrix

Voir cet exemple en SVG (seulement avec navigateur gérant SVG)
 

15.11 La primitive de filtre 'feComponentTransfer'

Cette primitive de filtre élabore une nouvelle carte des données, selon la composante et pour chaque pixel, comme suit :

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

Elle autorise des opérations comme l'ajustement de la luminosité, du contraste, de l'équilibre des couleurs ou du seuil.

Les calculs s'effectue sur des valeurs de couleur non prémultipliées. Si le graphique en entrée consiste en valeurs de couleur prémultipliées, celles-ci sont automatiquement converties en valeurs de couleur non prémultipliées pour cette opération. (Remarquer que le défaire et le refaire de la prémultiplication peuvent être évités si la composante feFuncA est la transformation à l'identique et si toutes les valeurs alpha du graphique source sont mises à 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; >
La spécification des fonctions de transfert est définie par les sous-éléments de 'feComponentTransfer' :
'feFuncR', la fonction de transfert pour la composante rouge du graphique en entrée
'feFuncG', la fonction de transfert pour la composante verte du graphique en entrée
'feFuncB', la fonction de transfert pour la composante bleue du graphique en entrée
'feFuncA', la fonction de transfert pour la composante alpha du graphique en entrée

Les attributs ci-dessous s'appliquent aux sous-éléments 'feFuncR', 'feFuncG', 'feFuncB' et 'feFuncA' qui définissent les fonctions de transfert.

Définitions des attributs :

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

Indique le type de la fonction de transfert de la composante. Le type de la fonction détermine l'application, ou non, des autres attributs.

  • Pour la valeur identity :
    C' = C
  • Pour la valeur table, la fonction est définie par interpolation linéaire dans une table indexée [N.d.T. lookup table] par l'attribut tableValues, qui fournit une liste de n+1 valeurs (i.e., v0 à vn) pour l'identification de n plages d'interpolation. Les interpolations utilisent les formules suivantes.

    Soit une valeur C, prendre un k tel que :

    k/N <= C < (k+1)/N

    Le résultat C' est donné par :

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

  • Pour la valeur discrete, la fonction est définie par la fonction en escalier définie par l'attribut tableValues, qui fournit une liste de n valeurs (i.e., v0 à vn-1) pour l'identification d'une fonction en escalier consistant en n marches. La fonction en escalier est définie par les formules suivantes.

    Soit une valeur C, prendre un k tel que :

    k/N <= C < (k+1)/N

    Le résultat C' est donné par :

    C' = vk

  • Pour la valeur linear, la fonction est définie par l'équation linéaire suivante :

    C' = slope * C + intercept

  • Pour la valeur gamma, la fonction est définie par la fonction exponentielle suivante :

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

Animable : oui.
tableValues = "(liste de valeurs <nombre>)"
Quand type="table", c'est la liste des valeurs de <nombre> v0,v1,...,vn, séparées par des blancs et/ou des virgules, qui définit la table indexée. Une liste vide résulte en une fonction de transfert à l'identique.
« errata 2002-11-15 » Si l'attribut n'est pas spécifié, alors l'effet produit est comme si on avait fourni une liste vide.
Animable : oui.
slope = "<nombre>"
Quand type="linear", c'est la pente de la fonction linéaire.
Si l'attribut n'est pas spécifié, l'effet produit est comme si une valeur de 1 était spécifiée.
Animable : oui.
intercept = "<nombre>"
Quand type="linear", c'est l'interception de la fonction linéaire.
Si l'attribut n'est pas spécifié, l'effet produit est comme si une valeur de 0 était spécifiée.
Animable : oui.
amplitude = "<nombre>"
Quand type="gamma", c'est l'amplitude de la fonction gamma.
Si l'attribut n'est pas spécifié, l'effet produit est comme si une valeur de 1 était spécifiée.
Animable : oui.
exponent = "<nombre>"
Quand type="gamma", c'est l'exposant de la fonction gamma.
Si l'attribut n'est pas spécifié, l'effet produit est comme si une valeur de 1 était spécifiée.
Animable : o