Accueil

Traduction

Tutoriel Canvas - sommaire

Tutoriel Canvas - recherche

L'auteur : Patrick Darcheville

Vous pouvez me contacter via Facebook pour questions & suggestions : Page Facebook relative à mon site

Insertion d'une image dans le canevas - les filtres

Dans ce chapitre je vais vous montrer comment insérer une image existante dans un canevas.
Sachez que désormais on peut appliquer aux objets du canevas des filtres avec la syntaxe CSS3.

Insertion dans le canevas faisant déjà partie du DOM


Comme vous le voyez ci-dessus, l'image qui est destinée à être insérée dans le canevas apparait dans la page ; donc fait déjà partie du DOM.

Ci-dessous le canevas avec cette image insérée deux fois dans le canevas.

Le code HTML

L'image sexy fait office de 'background' de la boite CANVAS.
Puis elle est insérée une deuxième fois mais avec réduction dans le coin bas droit du canevas.

La fonction correspondante

...
	var image = document.getElementById('brune'); // cibler l'image du DOM
	var canevas = document.querySelector('#canevas1'); 
	var contexte = canevas.getContext('2d');
	var X =canevas.width;
	var Y =canevas.height;
	 
	contexte.drawImage(image,X/2,Y/2,X/2,Y/2) ;
	
	contexte.fillStyle = 'red';
	contexte.textAlign ='center'; 
	contexte.textBaseline = 'middle'; 
	contexte.font = " bold normal 40px arial" ; 
	contexte.fillText('Page réservée aux adultes', X/2, Y/3) ; 
...

Pour insérer une image avec une certaine taille et position dans le canevas il faut utiliser la méthode drawImage avec cinq paramètres : référence objet, x, y, width, height.
x et y étant les coordonnées de l'image dans le canevas.
Si les dimensions d'affichage ne sont pas précisées, l'image est insérée avec ses dimmensions d'origine.

Insertion dans un canevas d'images qui ne sont pas dans le DOM

Si les images à insérer dans le canevas ne font pas partie du DOM, la technique d'insertion est un peu plus lourde ...

La méthode drawImage() a besoin que l’image ait été complètement chargée pour fonctionner.

Ci-dessous le deuxième canevas de cette page avec insertion de deux images qui ne font pas partie du DOM généré par le HTML : lune.gif & terre.gif.

Le code HTML

La fonction JS (extrait)

...
	var lune =new Image();
	var terre = new Image();
	lune.src = '../images/lune.gif' ;
	terre.src = '../images/terre.gif'; 
	
	var canevas = document.querySelector("#canevas2");
	var contexte = canevas.getContext('2d');
	// dessin des images après leur chargement
	lune.onload =function()
		{ contexte.drawImage(lune,10,10,50,50) ; }
	terre.onload = function()
		{contexte.drawImage(terre,300,300,200,200) ;}
...

Il faut créer de nouveaux objets de type Image, les charger et enfin les dessiner.

Astuce : charger les images via HTML

Plutôt que charger les images via le script, vous pouvez les charger via le HTML sans que pour autant elles apparaissent dans la page ; il suffit d'appliquer aux images la propriété display : none dans la balise IMG.

Des images du DOM sont masquées !

Oui, les images sont déformées.

Le code correspondant

Le script est beaucoup plus simple que le précédent car j'ai chargé les images (mais sans les afficher) via le HTML.
Les images insérées sont déformées ! Ci-dessous la solution pour éviter tout risque de déformation.

Insertion d'images sans déformation

Attention si vous ne prenez pas certaines précautions l'image insérée risque d'être déformée.

Ci-dessous un canevas incorporant deux images : la première est déformée et la seconde ne l'est pas.

Affichez la console !

Le code correspondant

Le canevas fait 300 par 450 et est identifié "canevas4". La première image fait 900 par 600, la deuxième image fait 400 par 600. Donc la première est plus large que haute et c'est l'inverse pour la seconde.

La fonction

...
	var canevas = document.querySelector("#canevas4"); 
	var contexte = canevas.getContext('2d');
	var X = canevas.width;
	var Y = canevas.height;

	var brune = new Image(); 
	brune.src ="../images/brune_nue.jpg"; 
	brune.onload =function()
	{contexte.drawImage(brune,0,0,X/2,Y/2); }

	var sexy = new Image(); 
	sexy.src ="../images/noire_bikini.jpg" ; 
	sexy.onload =function()
	{
		largeur =sexy.width; 
		hauteur =sexy.height; 
		ratio = hauteur /largeur; 
		largeur_fixee = X/2; 
		hauteur_fixee = largeur_fixee * ratio; 
		console.log(largeur); 
		console.log(hauteur);
		console.log(ratio); 
		contexte.drawImage(sexy,X/2,Y/2,largeur_fixee,hauteur_fixee) ;
	} // fin fonction anonyme
...

La routine pour insérer la deuxième image est un peu plus longue pour la première mais assure aucune déformation de l'image insérée.
Il suffit de récupérer les dimensions de l'image chargée, de calculer le ratio hauteur/largeur, de calculer les dimensions d'affichage dans le respect du ratio largeur/hauteur.

On peut cependant regretter que la fonction drawImage doit être argumentée obligatoirement avec 3 ou 5 paramètres ; que l'on ne puisse pas préciser uniquement la largeur OU hauteur désirées (à charge pour la fonction de recalculer l'autre dimension dans le respect du ratio d'origine).

Filtre les objets du canevas

Encore une bonne nouvelle. C'est désormais très facile de filtrer les images insérées dans un canevas ; aussi simple qu'en CSS grâce au module CanvasRenderingContext2D.filter.

Exemple 1

Ci-dessous rendu d'un document HTML contenant un canevas qui insère 4 fois la même image : version originale, sépia, floutage, inversion.

Le script dans ce document :

...
var X =canevas.width;
var Y =canevas.height;
var jolie = new Image(); 
jolie.src ="../images/jolie_fille.jpg" ; 
jolie.onload = function()
{
	contexte.drawImage(jolie,0,0, X/2,Y/2);

	contexte.filter ="sepia(1)"; 
	contexte.drawImage(jolie,300,0, X/2,Y/2); 

	contexte.filter ="blur(3px)"; 
	contexte.drawImage(jolie,0,400, X/2,Y/2); 

	contexte.filter ="invert(1)"; 
	contexte.drawImage(jolie,300,400, X/2,Y/2); 
 }  // fin fonction anonyme 
...

Si vous connaissez les filtres en CSS, vous reconnaissez la syntaxe.

Exemple 2

Il est possible de chainer plusieurs fonctions de filtre.

Ci-dessous un document HTML contenant un canevas. Ce dernier insère une photo deux fois avec à chaque fois deux primitives : floutage et nuance de gris pour la première insertion ; floutage et rotation dans l'axe chromatique pour la deuxième insertion.

Le script dans ce document:

...
var X =canevas.width;
var Y =canevas.height;
var jolie = new Image(); 
jolie.src ="../images/jolie_fille.jpg" ; 
jolie.onload = function()
{

	contexte.filter = "grayscale(100%)  blur(3px)";
	contexte.drawImage(jolie,0,0, X/2,Y);

	contexte.filter = "hue-rotate(270deg)  blur(3px)";
	contexte.drawImage(jolie,300,0, X/2,Y); 
}// fin fonction anonyme 
...

Notez la valeur de la propriété filter : il suffit de séparer d'un espace les différentes primitives.

Ombrer les formes et chemins avec des filtres CSS

Un filtre avec la syntaxe CSS peut être basé sur la fonction drop-shadow(). Ce filtre a alors pour effet d'ombrer les objets du canevas.
Ci-dessous un document HTML contenant un canevas :

Le code HTML

Notez le dégradé linéaire en arrière plan du canevas.

Le script qui remplit ce canevas se résume en six lignes :

var canevas = document.querySelector('canvas'); 
var contexte = canevas.getContext('2d');
contexte.fillStyle ="white";
contexte.filter = "blur(1px) drop-shadow(10px 10px 5px gray)";
var croix = new Path2D('M170,50 h60 v50 h60 v60 h-60 v90 h110 v60 h-110 
	v90 h-60 v-90 h-110 v-60 h110 v-90 h-60 v-60 h60 v-50 z'); 
contexte.fill(croix); 

Une seule instruction pour dessiner le chemin et une seule ligne pour ombrer l'objet.
Un filtre avec deux primitives : blur & drop-shadow.
Comme la propriété CSS box-shadow, la fonction drop-shadow prend quatre arguments : offsetX, offsetY, floutage, couleur. Les deux premiers arguments peuvent être négatifs.

Pour connaitre les différentes valeurs possibles de la propriété filter : les filtres en CSS