SVG : images vectorielles

Il existe plusieurs formats pour représenter une image vectorielle mais le format soutenu par le World Wide Web Consortium est le format SVG.
Une image vectorielle est donc un fichier d'extension .svg contenant du code SVG mais aussi du CSS voire du JavaScript.

Le format SVG est dédié au web. Pour afficher une image SVG il faut ouvrir le fichier avec un navigateur.
Il est impossible d'ouvrir une image SVG avec un logiciel graphique tel Paint (logiciel ne pouvant modifier que les images matricielles).

Premier exemple d'image vectorielle SVG

une image vectorielle SVG

Faites un clic droit sur l'image. Comme pour une image bitmap vous pouvez l'enregistrer sur votre ordinateur puisque le menu contextuel vous propose la commande "Enregistrez l'image sous".
Faites le ! Vous récupérez sur votre machine un fichier nommé "deux_rectangles.svg".
Essayez de l'ouvrir avec le logiciel PAINT ; vous avez un message d'erreur :" Paint ne peut pas lire ce fichier. Format non pris en charge" ; En effet PAINT ne peut ouvrir que les images matricielles (png, jpg et gif).
Essayez maintenant de l'ouvrir avec un éditeur de textes tel NOTEPAD. C'est possible et vous voyez alors un code.
Essayez ensuite d'ouvrir le fichier avec Inkscape (un éditeur WYSIWIG de fichier au format SVG) ; l'image apparait et vous pouvez la modifier en mode graphique.

Le code SVG de cette image

<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="600px" height="200px"> <title>images vectorielles SVG</title> <desc>Dessin de deux rectangles noirs</desc> <rect x="30px" y="30px" width="300px" height="50px" ></rect> <rect x="150" y="100" width="300" height="100" rx = '20' ry = '10' /> </svg>

Commentaire du code

A la différence d'une image matricielle il ne s'agit pas d'un "bouillon de pixels" mais de formules mathématiques !

Le langage SVG est basé sur le XML. Donc dans le code d'un fichier SVG vous retrouvez la déclaration XML (première instruction).
Vous avez ensuite le DOCTYPE.

A l'instart de l'élément HTML pour une page web le conteneur SVG représente la racine de notre document.

Dans la balise SVG vous avez deux attributs xmlns et xmlns:xlink.
xmlns comme XML name space ou "espace de noms".

Les langages basées sur le XML sont très nombreux et peuvent utiliser les mêmes noms de balise mais avec des sens différents. Grâce à la valeur de l'attribut xmlns="http://www.w3.org/2000/svg" vous précisez bien que ces balises et attributs sont utilisés dans le cadre du format SVG.

Mais il y a un deuxième espace de noms : xmlns:xlink="http://www.w3.org/1999/xlink"
Cette spécification est indispensable lorsque vous voulez créer des liens entre un fichier SVG et d'autres fichiers tels des images matricielles. Donc ici elle n'est pas nécessaire.

La balise SVG contient aussi les attributs width & height.
Dans l'exemple les valeurs sont 600 pixels et 200 pixels. Or nous savons que dans le cadre du responsive design il faut mieux exprimer les largeurs en % ...

A l'intérieur du conteneur SVG nous trouvons deux balises : title et desc. Ces deux balises sont facultatives mais sont utiles pour le référencement du document.

Puis nous trouvons deux fois la balise rect. Cette balise permet de dessiner un rectangle.
Le premier rectangle est plus précisément un carré (largeur = hauteur). Dans le deuxième rectangle les angles sont arrondis.
Les deux formes sont remplies de noir !
Donc SVG c'est comme du HTML : des balises avec des attributs !

Examinons de plus près l'instruction qui permet de dessiner le premier rectangle !

<rect x="30px" y="30px" width="100px" height="100px" ></rect>
En XML les balises vont par paires : une balise ouvrante et une balise fermante.
La balise rect permet de créer un rectangle à partir de quatre attributs obligatoires : x et y (coordonnées de l'arête supérieure gauche du rectangle) ; width et height (dimensions du rectangle).
Par défaut une forme est remplie de noir. Nous verrons plus loin les attributs ou propriétés de mise en forme.

Examinons l'instruction qui permet de dessiner le deuxième rectangle !

Pour le deuxième rectangle j'ai écrit x = 150 y = 75 ... . En effet par défaut l'unité de mesure est le pixel. Donc on peut écrire "150" à la place de "150px".
Dans ce deuxième rectangle les angles sont arrondis car il y a deux attributs supplémentaires : rx et ry (rayon horizontal et rayon vertical de chaque arrondi). Si un seul de ces attributs est précisé ils sont supposés être égaux (rx = ry).
Remarquez aussi que la balise fermante </rect> a disparu ! Par contre la balise début est fermée.
En effet si une balise n'a pas de contenu on peut alors simplifier la syntaxe : supprimer la balise fermante à condition de bien "fermer" la balise ouvrante (barre oblique avant parenthèse fermante).

Autre exemple de fichier SVG : "rue.svg"

Le rendu dans la page web

image vectorielle SVG

Le code de ce fichier

<?xml version="1.0" encoding="utf-8"?> <svg width="100%" height="auto" xml:lang="fr" viewBox ="0 0 500 300" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <rect x="0" y="0" width ="500" height ="200" fill ="skyblue" /> <rect x="0" y="200" width ="300" height ="40" fill ="slategray" /> <rect x="0" y="245" width ="300" height ="55" fill ="gray" /> <polygon points ="300,200 500,120 500,140 300,240" fill ="slategray" /> <polygon points ="300,245 500,140 500,300 300,300" fill ="gray" /> <desc>maison de gauche</desc> <rect x="0" y ="100" height ="100" width ="100" fill ="salmon" /> <polygon points ="0,100 10,40 110,40 100,100" fill ="red" /> <rect x="10" y ="110" width ="20" height ="30" fill = "black" /> <rect x="70" y ="110" width ="20" height ="30" fill = "black" /> <rect x="10" y ="150" width ="20" height ="30" fill = "black" /> <rect x="70" y ="150" width ="20" height ="30" fill = "black" /> <rect x="40" y ="150" width ="20" height ="50" fill = "black" /> <rect x="10" y ="80" width ="20" height ="20" fill ="black" /> <polygon points ="30,80 40,70 30,100" fill ="darkred" /> <rect x="70" y ="80" width ="20" height ="20" fill ="black" /> <polygon points ="90,80 100,70 90,100" fill ="darkred" /> <desc>maison du milieu</desc> <rect x="100" y ="70" height ="130" width ="100" fill ="wheat" /> <polygon points ="100,70 110,10 210,10 200,70" fill ="darkred" /> <rect x="110" y ="0" width ="10" height ="40" fill ="wheat" /> <polygon points ="120,0 130,0 130,10 120,40" fill ="tan" /> <rect x="110" y ="80" width ="30" height ="30" fill = "black" /> <rect x="160" y ="80" width ="30" height ="30" fill = "black" /> <rect x="110" y ="140" width ="30" height ="60" fill = "black" /> <rect x="160" y ="140" width ="30" height ="30" fill = "black" /> <desc>maison de droite</desc> <rect x="200" y ="90" height ="110" width ="100" fill ="sandybrown" /> <polygon points ="200,90 210,40 310,40 300,90" fill ="crimson" /> <rect x="210" y ="0" width ="10" height ="50" fill ="sandybrown"/> <polygon points ="220,0 225,0 225,40 220,50" fill ="tan" /> <polygon points ="200,70 210,10 210,40 200,90" fill ="tan" /> <polygon points ="300,90 310,40 340,70 340,185 300,200" fill ="tan" /> <rect x ="210" y ="100" width ="20" height ="30" fill ="black" /> <rect x ="240" y ="100" width ="20" height ="30" fill ="black" /> <rect x ="270" y ="100" width ="20" height ="30" fill ="black" /> <rect x ="210" y ="150" width ="20" height ="30" fill ="black" /> <rect x ="240" y ="150" width ="20" height ="50" fill ="black" /> <rect x ="270" y ="150" width ="20" height ="30" fill ="black" /> <polygon points ="300,200 340,185 440,205 450,220 410,220" fill ="black" fill-opacity ="0.5"/> <desc>mur</desc> <polygon points ="340,140 500,100 500,120 340,185" fill ="tan" /> <polygon points ="340,185 500,120 500,130 380,195" fill ="black" fill-opacity ="0.5" /> <text x ="350" y="280" style ="font-family : cursive ; font-size : 14px ;">Patrick Darcheville</text> </svg>

J'ai dessiné sur une feuille à petits carreaux dans un repère (50 carreaux sur 30 donc 1 carreau = 10) les différentes formes. A partir de ce croquis je détermine facilement les coordonnées des formes.
Il est ensuite très simple de coder avec un éditeur tel NotePad. Pour chaque forme je précise la couleur de remplissage avec l'attribut fill avec pour valeur le nom anglais de la couleur (ou code RGB ou code hexadécimal).

Troisième exemple d'image SVG

Image que j'ai récupéré sur la toile. Je remercie pas avance son auteur. image vectorielle SVG

Le code SVG de cette image vectorielle

<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg version="1.1" id="napoleon4" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="100%" height="auto" viewBox="0 0 309 419" enable-background="new 0 0 308.7 419" xml:space="preserve" > <g id ="visage"> <path fill="#195073" d="M48.2,296.4c5,8,9,16,12,25c6,14,12,30,27,38.2c2.4,1.5,5,2.8,7.6,3.9c8.8,3.3,17.8,4.3,26.7,3.8 c3-0.2,5.9-0.6,8.8-1.1c25.9-6.7,49.9-20.7,69.9-38.7c-1,2,1,3,2,4c0-2,0-3,0-5c1.5-3,4-5.2,5.6-7.6s2.4-4.9,0.4-8.4c2-1,5-3,5-4 c5-9,8-19,7-29c0,2-1,4-2,5c-8,2-8-9-6.1-13.9c0.4-3.9,0.6-7.6-1.9-11.1c-1-2,3-4,3-6c1-2-4-3-3-3c14-16,18-36,31-51.8 c0.9-2.7,1.1-5.5,0.8-8.3c-1.2-11.2-10.7-22.4-16.5-29.5c-1.8-1.3-3.8-2.2-6.3-2.4c0,1,0,2,0,3c-1,0-3,0-4,0c4-9,0-22-10-26 c1-2,7-3,4-5c-1-2-5,2-9,1c1-1,2-2,4-2c2-3,0-4-2-4c-1,0-2,1-3,2c9.8-3,13.3-11.1,14.1-20c0.2-3,0.2-6-0.1-9c0,1,1,2,1,3 c4-6-3-11-2-17c0,2,1,4,0,5c-3,2-3-3-4-4c-1,5-5,6-7,10c-2-4-1-7-1-11c-1,2-1,3-1,5c-1-5-1-10-3-14c0,2-2,3-4,3c0-2,0-5-1-7 c-3-7-14-11-16-5c-4,8-5,8-13.5,9.5c-3.5,0.8-6.5,0.5-8.5-4.5c-1,5,8,8,4,11c-5,4-11-6-15,2c0,0-2-1-3-1c0,11,9,16,17,21 c-3-1-7-2-9,0c0,1,1,3,3,3c-6,0-14-4-17,3c-1-1-1-4-2-4c-13,1-19-11-31-15c1,5,6,7,7,10c2,3-3,4-5,1c0,1,0,3-1,3c-6,1-7-5-11-7 c1,4,4,7,7,10c-7-3-13-8-18.3-13.1c-1.5-1.8-2.7-3.7-3.8-5.7c-2.2-4-3.9-8.2-6.9-12.2c-1,4-2,8-6,8c-3,1-2-6-3-5 c-12,4-18,19-22,32.3c-0.9,3.1-1.6,6.2-2.2,9.3c-1.2,6.3-1.7,12.8-1.8,19.3c0,2.2,0,4.4,0.1,6.6c-0.1,4.4,1.9,9.4,0.9,13.4 c-1,2.5-2,5.8-2,8.8c-1,4.2,2,6.2,4,7.2c15,6,33-5,46,6c-1,1-1,1-2,2c9,1,13,10,13,18c-2-1-4-3-7-2c1,1,2,2,3,3c-1,1-1,1-2,2 c1,0,3,0,4,1c-1,0-3,1-4,1c-2,0-4-4-6-4c-2,1-3,4-5,5c-10,5-11-4-18-7c-2-1-2,7-2,11c-1-1-2-2-3-1c-2,4,4,3,5,5c0,2-2,4-4,4 c-7-1-10-10-16-13c-8-5-7-20-11.4-30.9c-1.1-2.7-2.5-5.3-4.1-7.8c-1.6-2.5-3.4-5-5.6-7.3c-3-2-5-7-4.8-10.9 c-0.5-2.6-0.8-5.2-0.8-7.9c-0.3-10.5,2.2-21.2,5.9-31.5c1.1-2.9,2.2-5.8,3.4-8.7c6.4-12.1,9.4-26.1,16.4-38.1c-1,1-3,1-4,1 c0-12,12-16,21-20c11-6,25-3,34.5-12.9c2.6-1.6,5.2-3.1,7.8-4.7c13.1-7.6,26.5-14,41.3-13.9c3,0,6,0.3,9,0.8 c3.4,0.6,6.4,2.6,9.4,2.6c13.3-2.7,26.7-3.6,39.1-0.3c3.1,0.8,6.2,1.9,9.2,3.3c2.7,1,5.1,2.4,7.3,4c6.4,6,12.4,13,19.4,16 c11,5,27,3,31,16c5,15,11,29,19,42c1.7,3.8,2.9,7.5,3.5,11.3c0.7,3.8,0.9,7.5,0.8,11.3c0,2.5-0.2,5.1-0.4,7.6 c0,2.8-0.1,5.6-0.2,8.4c-0.1,2.8-0.3,5.6-0.4,8.4c-2.4,20,6.6,38-0.4,57c2,0,3-1,3-3c-1.5,9-2.2,17.5-4.7,25.1 c-0.8,2.5-1.8,5-3.2,7.2c-2.2,5.7-8.2,8.7-13.2,11.7c-4,3-6,8-6,12c-2.7,11.3-0.9,23.1-2.3,34.1c-0.4,2.8-0.9,5.5-1.8,8.1 c-7.9,13.9-18.7,25.6-30.2,36.6c-2.3,2.2-4.6,4.4-7,6.6c-21.7,19.6-46.7,42.6-78.7,43.6c8,1,15-3,23-5c-1-1-3-1-4-2c2,0,4,1,5-2 c-11,5-22,10-35.3,9.5c-3.1,0.1-6.3-0.1-9.4-0.4c-9.3-1-18.2-4-25.9-9.3c-2.5-1.7-4.8-3.5-7.1-5.5c-1.7-1.5-3.3-3.1-4.9-4.7 c-1.6-1.7-3.1-3.5-4.6-5.4C64.3,339.4,51.3,319.4,48.2,296.4L48.2,296.4z M51.4,187.9c2.7,3.1,3.3-1.9,5.1-2 c-2.4,5.1-2.9-7.8-5.4,2.3c-0.1-1-1.3-2.9-1.4-3.9c0.4,3-2.7,2.1-3.6,3.2c1,0,3,0.9,3.7,0.7C50.4,188.2,50.9,188,51.4,187.9z M279,209.3c-1.9,2.6-4.3,4.8-6.4,7.2c-2.1,2.4-4,4.8-4.7,7.8c-0.3,3.9,5,6,8.3,2.1c1.8-2.2,2.9-4.7,3.5-7.4 c1.7-7.9-0.9-17.1-2.4-24.6c0,4-7,9-2,12.9C276.5,207.8,277.6,208.5,279,209.3z M283.2,168.2c-8-4.8-16,5.2-18,12.2 c6-2,8-9,15.4-8.4C282.5,171.4,283,170.3,283.2,168.2z M52.3,196.4c5-2,11-1,15-6c-4,0-9,0-13.3,1.9 C51.1,192.9,50.7,194.4,52.3,196.4z M260.2,238.7c-3.9,2.3-8.5,1.9-8.8,6.7c2.3,0.2,3.5-0.7,5.8-1.6 C258.7,242.4,259.2,240.4,260.2,238.7z M261.8,230.1c-4.8,0.1-6.3,1.1-6.5,4.1C259.8,234.7,260,232,261.8,230.1z"/> <path fill="#195073" d="M172.5,178.4c-11.3-3-21.3,2-30.3,8c12-5,25-3,37-4c-1-1-3-2-4-3c5-5,12,2,16-3c0,0-1-1-1-2c3,0,2,4,4,4 c6-1,19-1,15,6c-6,8-18,10-26,18c-2,3-7,5-11,2c3-3,9-2,10-8c-11-1-24,7-30-8c-1-3-9,5-10,11c-3-2-6,2-9,1c-1-2,4-5,1-6s-6,0-9,1 c0-1,0-2,0-3c-3,2-7,1-7,0c-1-5-1-13,5.7-14.8c-0.2-0.7-0.5-1.5-0.8-2.4c2.9-1,5.7-2,8.6-3c15.6-4.8,34.6-11.8,50.6-1.8 c-7,1-14,0-20,4c2,1,4,1,5.6,1C169.7,175.7,171.5,176.3,172.5,178.4z"/> <path fill="#195073" d="M132.3,258.5c0.9-0.1,2.9-0.1,3.9-0.1c3,5,2,12-3,14c-9,4-14,9-20,15c-5.5,5.5-9.5,2.8-13.5-2 c-2-2.4-4-5.2-6.2-7.8c-3.3-4.2-10.3-6.2-8.3-12.2c2,3,5,5,7.2,7.6c2.8,1.4,5.8,1.4,8.8-0.6c9-5,17-6,26.4-9.6 C131.2,263.5,132,261.2,132.3,258.5z"/> <path fill="#195073" d="M83.2,300.6c0,0.8,1,1.8,1,2.8c5-4,11-4,16.9-2.4c2.1,0.6,4.1,1.4,6.1,1.4c16-2,35-11,50.6-4 c0.4-0.7,0.7-1.2,1.1-1.9c1.3,1.9,3.3,3.9,5.3,4.9c-2,3-5-2-6.9,0.7c-0.7,0.4-1.8,0.2-2.8,0.2c-15.8,3.8-32.3,4.1-48.5,4.9 c-3.3,0.1-6.5,0.3-9.8,0.4c-6.9-0.3-12.9,1.7-19.9,0.8C76.4,303.8,78.7,301,83.2,300.6z"/> <path fill="#195073" d="M130.5,311.9c2.7-1.5,5.7-2.5,8.7-2.5c0-1-1-1-1-2c2-1,5,0,4,2c-4.2,13.3-19.4,14.2-32.5,12.3 c-2.6-0.4-5.1-0.8-7.5-1.4c-3-1.1,2-3,3-3c2-0.2,4.3-0.2,6.7-0.1c7.3,0.3,15.5,1.2,19.1-4.5C130.9,312.6,130.7,312.2,130.5,311.9z" /> <path fill="#195073" d="M48.3,296.3c-5-8.9-7-17.9-9.1-27.7c-0.5-2.5-1-5.1-1.5-7.7c-0.5-2.5-0.9-5.1-1.4-7.6 c0.8,2.5,1.8,5,2.8,7.5c1,2.5,2,5,3,7.5C46.3,277.4,49.3,286.4,48.3,296.3C48.2,296.4,48.3,296.3,48.3,296.3z"/> <path fill="#195073" d="M34.5,248.7c-0.1-2.6-0.6-5-1.2-7.1c-0.6-2.2-1.2-4.1-1.5-6.1c2.8,2,3.7,4,3.6,6.7 C35.9,244.6,35.6,247,34.5,248.7z"/> <path fill="#195073" d="M123.7,384.8c2.3-1.2,4.4-1.3,6.6-1.1c2.2,0.2,4.4,0.7,6.9,0.6c-2,1-5,1.1-6.5,1.3 C128.4,385.8,125.8,385.5,123.7,384.8z"/> </g> </svg>

Le code semble plus compliqué que dans le deuxième exemple. Mais rassurez vous il n'a pas été saisi par un individu.
Le code SVG a été généré avec un logiciel de dessin doté d'une interface graphique. Ici c'est avec Adobe Illustrator mais ça pourrait être Inkscape. Cette image vectorielle ne pèse que 6 KO.

Vous retrouvez la balise SVG avec les "namespace".

Dans le corps du document figure plusieurs fois la balise path. Cette balise permet de réaliser des formes complexes : suite de droites et de courbes.
Remarquez que pour les balises path la notation simplifiée a été pratiquée (pas de balise fermante) mais fermeture de la balise ouvrante.
Par contre pour la balise g (pour grouper des formes) la notation simplifiée est impossible puisqu'il s'agit d'un conteneur : contient plusieurs fois la balise path !!!

Divers

L'attribut viewBox

Il y a une différence fondamentale entre la première image SVG et les deux suivantes.
Dans les trois extraits de code regardez attentivement la balise SVG début : celle qui contient les différents attributs.
Dans les deuxième et troisième fichier il existe un attribut : viewBox qui est absent de la première image SVG.
Je n'en dis pas plus pour le moment. Mais sachez que cet attribut est très important.

Affichage de l'image SVG dans une page web

Pour insérer une image vectorielle de format SVG dans une page web il suffit d'utiliser la balise img comme n'importe quelle image.

Extrait du code de la page :

<img src ="deux_rectangles.svg" alt ="image vectorielle SVG" width ="60%" /> ... <img src ="rue.svg" alt ="image vectorielle SVG" width ="60%"/> ... <img src ="napoleon1.svg" alt ="image vectorielle SVG" width ="60%"/>

Donc l'insertion dans une page web d'une image vectorielle (fichier SVG) se fait comme pour une image matricielle (fichiers JPG, PNG,GIF) avec la balise img !
Dans le cadre du "responsive design" la largeur d'affichage est exprimée en %.
Vous verrez plus tard que dans certains cas l'incorporation d'une image SVG dans une page web doit se faire avec la balise object. Mais rassurez vous nous aurons l'occasion d'y revenir.
Vous verrez aussi que le code SVG peut être directement écrit dans une page web (à l'intérieur de la balise HTLM5 SVG). Dans ce cas l'attribut viewBox prend toute son importance. Mais j'aurai l'occasion d'y revenir.
Retour menu