Outils pour utilisateurs

Outils du site


p5.js:modifier_une_image_pixel_par_pixel


Modifier une image pixel par pixel


Dans ce cours, vous allez modifier une image pixel par pixel, pour par exemple :

  • modifier les couleurs d'une image en noir et blanc ;
  • modifier les couleurs d'une image en niveaux de gris ;
  • inverser les couleurs d'une image ;
  • créer l'image symétrique d'une image de départ…


Comment charger une image ?

La première étape avant toute transformation est de charger puis d'afficher une image. Normalement, vous maitrisez cette étape. Si nécessaire, revoir le cours correspondant : Utiliser des images

A faire vous-même 1

- Télécharger l'image ci-dessous et la placer dans votre dossier medias.

- Saisisser et tester le code suivant :

var img;
function preload() {
   img = loadImage("medias/photo1.jpg");
}
function setup() {
   createCanvas(800, 600);
}
function draw() {
   image(img, 0, 0);
}


Comment obtenir la couleur d'un pixel ?


Pour obtenir la couleur d'un pixel d’une image, on peut utiliser la fonction get(x,y), où x et y sont l’abscisse et l’ordonnée du pixel dont on veut connaître la valeur.

Par exemple pour connaître la couleur du pixel de coordonnées (100,50) de l’image img, il me suffit d’écrire :

couleur = img.get(100,50);

Le code précédent retourne dans la variable couleur un tableau contenant les informations pour le canal rouge, le canal vert, le canal bleu et pour le canal alpha du pixel : couleur[R, V, B, alpha].

Pour extraire de la variable couleur la valeur du canal rouge, vert et bleu, on peut utiliser les fonctions red(), green() et bleue() :

  R = red(couleur);
  V = green(couleur);
  B = blue(couleur);


Une autre méthode est possible en parcourant le tableau couleur :

  R = couleur[0];
  V = couleur[1];
  B = couleur[2];


A faire vous-même 2

Compléter le sketch précédent afin d'afficher un cercle de la couleur du pixel survolé par la souris ainsi que le code RVB.


Comment définir la couleur d'un pixel ?


Il est possible de définir la couleur d'un pixel à l'aide de la fonction set().

Exemple : le pixel situé sous la souris devient rouge.

function draw() {
  couleur = color(255, 0, 0, 255);
  set(mouseX, mouseY, couleur);
  updatePixels();
}

La fonction color(255, 0, 0, 255) permet de stocker une couleur dans la variable couleur. Les paramètres sont des codes RVBa.

Après avoir utilisé set(), vous devez appeler updatePixels() puis afficher l'image pour que vos modifications apparaissent.



Comment modifier une image en niveaux de gris ?



Pour rappel, un pixel sera dans un niveau de gris si la valeur rouge, verte et bleu du code RVB est la même.

Exemple : Ce texte gris a pour code RVB (169, 169, 169).

La méthode pour obtenir une image en niveaux de gris se fait en trois étapes :

  • Obtenir les valeurs rouge, verte et bleue d'un pixel ;
  • Utiliser une formule mathématique pour transformer ces nombres en une seule valeur de gris ;
  • Remplacer les valeurs d'origine rouge, verte et bleue par la nouvelle valeur de gris.

La formule mathématique la plus simple est de calculer la moyenne de la valeur rouge, verte et bleue pour chaque pixel : gris = (Rouge + Vert + Bleu) / 3

Un exemple de sketch permettant de modifier une image en niveau de gris :

var img;
 
function preload() {
  img = loadImage("photo.jpg");
}
 
function setup() {
  var largeur = img.width;   // largeur de l'image
  var hauteur = img.height;  // hauteur de l'image
  createCanvas(largeur, hauteur); // créer un canvas de la taille de l'image
  image(img, 0, 0);   // afficher l'image
 
  for (var x = 0; x < largeur; x = x + 1) {      // deux boucles pour parcourir l'ensemble
    for (var y = 0; y < hauteur; y = y + 1) {   // des pixels constituant l'image
 
      var couleur = get(x, y);   // obtenir la couleur du pixel (x,y)
 
      var R = red(couleur);     // R prend la valeur du rouge
      var V = green(couleur);   // V prend la valeur du vert
      var B = blue(couleur);    // B prend la valeur du bleu
 
      var gris = (R + V + B) / 3;   // calcul de la valeur du gris
 
      set(x, y, gris);   // definir la nouvelle couleur du pixel (x,y)
    }
  }
  updatePixels();   // mettre à jour les pixels modifiés
}



La seule véritable difficulté de ce sketch est de bien comprendre la structure de la double boucle.

  for (x = 0; x < largeur; x = x + 1) {    
    for (y = 0; y < hauteur; y = y + 1) {   
       ...
    }
  }

Grâce à cette animation, cette double boucle n'aura plus de secret pour vous : (en construction…)



Remarque importante :

La formule précédente pour calculer les nuances de gris n’est pas sans inconvénients : bien que rapide et simple, elle représente mal les nuances de gris par rapport à la façon dont l’être humain perçoit la luminosité.
La densité de cônes dans l'œil humain n'est pas uniforme dans toutes les couleurs. Les humains perçoivent le vert plus fortement que le rouge et le rouge plus que le bleu.
Au lieu de traiter les lumières rouge, verte et bleue de la même manière, la formule couramment utilisée dans les logiciels d'images (Photoshop, GIMP… ) est la suivante : gris = Rouge x 0.3 + Vert x 0.59 + Bleu x 0.11

A faire vous-même 2

- Remplacer la formule pour calculer le niveau de gris par celle utilisée par les logiciels de dessin : gris = R * 0.3 + V * 0.59 + B * 0.11).

- Testez, voyez-vous une différence ?



Comment transformer une image en noir et blanc ?

Une image “noir et blanc” est uniquement composée de pixels noirs et de pixels blancs !

Pour transformer une image en noir et blanc, il suffit de reprendre la méthode pour transformer une image en niveaux de gris, puis si la variable gris > 128 alors attribuer au pixel la couleur noir (0) sinon la couleur blanche (255).

Remarque : la valeur 128 correspond aux 256 valeurs possibles de nuances de gris divisée par 2.

A faire vous-même 3

Modifier le sketch précédent pour transformer une image en noir et blanc.



Comment permuter les couleurs d'une image ?


A faire vous-même 4

Modifier le sketch précédent pour permuter les couleurs de l'image.
Par exemple un pixel de couleur (240,15,180) prendra comme nouvelle couleur (180,15,240) soit une permutation du rouge et du bleu.



A faire vous-même 5 (pour les plus rapides)

Pleins d'autres possibilités à reproduire :



Comment obtenir une image symétrique par rapport à un axe ?


A faire vous-même 6

Toujours à partir du même sketch, réaliser les modifications pour afficher l'image symétrique par rapport à un axe verticalement ou horizontalement.

Une nouvelle image à télécharger.

Symétrie par rapport à un axe horizontal

Symétrie par rapport à un axe vertical



Une autre méthode pour modifier une image pixel par pixel

Cette méthode est basé sur l'utilisation d'un tableau à une seule dimension contenant les codes RVBa de tous les pixels d'une image.
Pour utiliser cette méthode, il est préférable de maitriser les tableaux en JavaScript : voir le cours.

L’image photo.jpg a pour taille 400 x 400 soit 160 000 pixels. Chaque pixel contient une couleur codée en RVB + canal alpha (transparence).

On peut accéder à ces pixels avec la fonction loadPixels() . Cette fonction place dans un tableau les informations pour le canal rouge, le canal vert, le canal bleu et pour le canal alpha des pixels de l’image.

Pour une image de 400 x 400, ce tableau comportera 400 x 400 x 4 = 640 000 éléments.

Attention, le premier pixel est le pixel 0 !

Une fois le tableau créé avec la fonction loadPixels(), il aura pour nom pixels[].

Pour récupérer les informations concernant le pixel de coordonnées (0,0), il faudra écrire :

  • pixels[0] pour avoir la valeur du canal rouge ;
  • pixels[1] pour avoir la valeur du canal vert ;
  • pixels[2] pour avoir la valeur du canal bleu ;
  • pixels[3] pour avoir la valeur du canal alpha.


Pour récupérer les informations concernant le pixel de coordonnées (1,0), il faudra écrire :

  • pixels[4] pour avoir la valeur du canal rouge ;
  • pixels[5] pour avoir la valeur du canal vert ;
  • pixels[6] pour avoir la valeur du canal bleu ;
  • pixels[7] pour avoir la valeur du canal alpha.


Pour récupérer les informations concernant le pixel de coordonnées (x,y), la formule suivante index = (x+y*width)*4 permet de calculer la valeur de l'index puis il faudra écrire :

  • pixels[index] pour avoir la valeur du canal rouge ;
  • pixels[index + 1] pour avoir la valeur du canal vert ;
  • pixels[index + 2] pour avoir la valeur du canal bleu ;
  • pixels[index + 3] pour avoir la valeur du canal alpha.


Le schéma ci-dessous, peut aider à comprendre la formule pour calculer la valeur de la variable index.

  • l'indice de chaque case du schéma ci-dessus est donné par la relation : x + y * width ;
  • dans chaque case il y a 4 informations (R, V, B, alpha) donc on multiplie par 4, soit index = (x+y*width)*4 .

Exemple : pour accéder au pixel de coordonnée (1,1), il faudra écrire : pixels[401 x 4] soit pixels[1604].

  • pixels[1604] contient la valeur du canal rouge ;
  • pixels[1604 + 1] contient la valeur du canal vert ;
  • pixels[1604 + 2] contient la valeur du canal bleu ;
  • pixels[1604 + 3] contient la valeur du canal alpha.


Une excellente vidéo pour comprendre l'utilisation de pixels[ ] : Daniel Shiffman

Un exemple de sketch permettant de modifier une image en niveau de gris en utilisant un tableau de pixels :

var img;
 
function preload() {
  img = loadImage("photo.jpg");
}
 
function setup() {
 
  var largeur = img.width;   // largeur de l'image
  var hauteur = img.height;  // hauteur de l'image
  createCanvas(largeur * 2, hauteur); // créer un canvas pour placer 2 images côte à côte
  image(img, 0, 0);   // afficher l'image
  img.loadPixels();   // création du tableau pixels[ ]
 
  for (var x = 0; x < largeur; x = x + 1) {      // deux boucles pour parcourir l'ensemble
    for (var y = 0; y < hauteur; y = y + 1) {   // des pixels constituant l'image
 
      var index = (x + y * largeur) * 4;  
 
      var R = img.pixels[index];     // R prend la valeur du rouge
      var V = img.pixels[index + 1];   // V prend la valeur du vert
      var B = img.pixels[index + 2];    // B prend la valeur du bleu
 
      var gris = R * 0.3 + V * 0.59 + B * 0.11;   // calcul de la valeur du gris
 
      img.pixels[index] = gris;     // definir la nouvelle couleur du pixel (x,y)
      img.pixels[index + 1] = gris;  
      img.pixels[index + 2] = gris;  
    }
  }
  img.updatePixels();   // mettre à jour les pixels modifiés
  image(img, 400, 0);  // afficher l'image en niveau de gris
}
p5.js/modifier_une_image_pixel_par_pixel.txt · Dernière modification: 10/07/2019 21:51 par Stéphane LAURENT