Niveau : Confirmé

Introduction à Canvas

Tutoriel par (Développeur, Strasbourg)
Créé le (22332 lectures)
Tags : pixel, canvas

Sommaire


Jouer avec les Pixels

Il faut le rappeler : Canvas est une surface de pixels. D'un point de vue de l'accessibilité (et par rapport à SVG) c'est un gros inconvénient car sans alternative c'est un véritable trou noir sans contenu propre. Si l'on place cet inconvénient de coté et que l'on fait appel à Canvas en conscience de cause, tous les pixels sont "accessibles" avec les méthodes createImageData (création ex-nihilo), putImageData (écriture) et getImageData (lecture).

Cela signifie que l'on peut opérer des traitements sur l'image, ou générer un tableau de pixels à partir d'un quelconque algorithme pour ensuite l'injecter sur la totalité ou une partie du dessin.

createImageData(x,y) crée un tableau de pixels RGBa de dimension (x * y). En revanche, il faut bien comprendre son fonctionnement vis-à-vis des pixels qui sont définis par 4 composantes et ne sont pas stockés un à un dans chacune des "cases" du tableau. Ce sont leurs valeurs Rouge, Vert, Bleu et Alpha qui remplissent individuellement et une à une ces "cases".

Au premier index [0] on retrouvera donc la valeur Rouge du premier pixel, puis dans [1] la valeur Vert, puis dans [2] la valeur Bleu et dans [3] la valeur Alpha (transparence). On retrouvera la valeur Rouge du second pixel à l'index [4], et ainsi de suite. Par exemple, createImageData(100,100) devra stocker l'information de 1000 pixels ce qui produira un tableau à 4000 valeurs.

  • [0] : R pixel 1
  • [1] : G pixel 1
  • [2] : B pixel 1
  • [3] : A pixel 1
  • [4] : R pixel 2
  • [5] : G pixel 2
  • [6] : B pixel 2
  • [7] : A pixel 2
  • ...

Pour parcourir l'ensemble des valeurs, pixel par pixel, il faudra sauter de 4 en 4 !

var imageData = ctx.createImageData(100,100);
var mapPixel = imageData.data; // Récupération du tableau de pixels dans la propriété data

// Accès à au premier pixels du tableau
mapPixel[0]; // valeur rouge du premier pixel
mapPixel[1]; // valeur verte du premier pixel
mapPixel[2]; // valeur bleue du premier pixel
mapPixel[3]; // valeur de transparence(alpha) du premier pixel

Le code ci-dessus est une simple représentation pour montrer que l'on peut facilement accéder aux valeurs de chaque pixel avec une boucle, tel que while ou for. La fonction createImageData(ImageData) peut aussi recevoir en argument une image source ce qui amène ensuite à la possibilité de faire des traitements et améliorations sur celle-ci. 

Les deux autres méthodes vont récupérer ou injecter les valeurs dans le canvas, à partir des données manipulées :

  • getImageData(x,y,width,height) : création d'un objet ImageData à partir d'une zone du contexte de dessin (portion du Canvas dont le coin supérieur gauche est défini par x,y et les dimensions par width et height).
  • putImageData(x,y) est la méthode de restitution/aposition de l'ImageData dans Canvas. Une fois tous les traitements finis, c'est cette fonction qu'il faudra appeler.

Canvas pixels

var imageData = ctx.createImageData(100,100);
var mapPixel = imageData.data; // Récupération du tableau de pixels

// On va rendre tout ça tout bleu avec une opacité de 50%
for(var i=0 ; i < mapPixel.length ;i+=4){
   mapPixel[i+2] = 200; // Bleu
   mapPixel[i+3] = 128; // Alpha
}
// On injecte les données au point 50,50
ctx.putImageData( imageData , 50 , 50 ); 

Démonstration

Retouche des pixels

Voici un traitement de l'image pour appliquer un "filtre" sur les différents canaux de couleurs.

var img_chat = new Image();
img_chat.src = "img/lyra.png";

img_chat.onload = function(){

	ctx.drawImage(img_chat, 75, 15);

	var copie_img_chat = ctx.getImageData( 75, 15, img_chat.width, img_chat.height);

	var data = copie_img_chat.data;

	for(var i = 0; i < data.length; i += 4) {
		var b = 0.3 * data[i] + 0.3 * data[i + 1] + 0.3 * data[i + 2];
		data[i] = b; // Rouge
		data[i + 1] = b; // Vert
		data[i + 2] = b; // Bleu
		// data[i+3] // Alpha (non modifié)
	}
	
	// copie le résultat 10px en-dessous de l'original
	ctx.putImageData( copie_img_chat, 75, 35 + img_chat.height );
}

Canvas Pixels et un chat

Démonstration

Commentaires

Didodu258 a dit le

Très bon tutoriel.
J'ai une remarque pour ceux qui voudrait essayer le programme de la section "Retouche des pixels" dans le chapitre "Jouer avec les Pixels".

Il semblerait que la plupart des navigateurs modernes n'exécutent pas la ligne contenant le getImageData pour des mesures de sécurité (quelques informations disponibles ici : goo.gl/p64w8 mais ça reste encore flou pour moi).

J'ai trouvé une solution sur le site stackoverflow.com pour ceux qui n'aurait pas d'hébergement et qui désirerait quand même utiliser ce code : il faut exécuter le script dans un serveur local (localhost). Personnellement j'ai utilisé wampserver et ça fonctionne parfaitement.

À part faire comme ça je n'ai pas trouvé d'autres solutions, si quelqu'un pouvait en dire plus...
(et si on pouvait ne pas supprimer mon commentaire...)

dew a dit le

C'est en effet une restriction de sécurité : il faut utiliser les ressources du domaine qui héberge déjà la page (afin de ne pas extraire les informations d'un domaine tiers). Donc localhost peut fonctionner pour les tests (plutôt qu'une adresse IP, ou un accès via file:// qui ne permet pas d'appliquer une règle de sécurité propre à un domaine).